From ripley at stats.ox.ac.uk  Thu Oct  9 17:14:55 2008
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Thu, 9 Oct 2008 16:14:55 +0100 (BST)
Subject: [Rd] LinkingTo on Windows
In-Reply-To: <405593F1A35DDD11B2B4000C29F5CF530344DE@exchange-server.ow.ks>
References: <405593F1A35DDD11B2B4000C29F5CF530344DE@exchange-server.ow.ks>
Message-ID: <alpine.LFD.2.00.0810091524590.28002@gannet.stats.ox.ac.uk>

On Tue, 7 Oct 2008, Thomas Baier wrote:

> Dear List,
>
> R packages may specify a "LinkingTo" attribute to specify dependencies to
> the source code (mainly the header files) of other packages.
>
> Unfortunately, it is not possible to also have a reference to the generated
> library (.dll on Windows) of the other package. So including a header file
> from another package to call an (exported) function will just not help.

Have you read the documentation for 'LinkingTo'?  That is not what it is 
documented to do, and it does work on Windows (as documented).

> I've tried to implement a workaround for my package rcom (depending on
> exported functions from rscproxy) by "manually" setting the library when
> linking, but unfortunately this does not work for me, when rscproxy gets
> installed into a different library (not the default one). OK, I could set
> the library path relative to the source drive and absolute for the standard
> library, so the "R CMD check" on CRAN is passed, but I don't think this
> would be a good solution.
>
> Of course, I could implement true dynamic binding by getting a handle to the
> rscproxy.dll (which already has been loaded at the time of loading rcom) and
> getting out procedure addresses, but I don't think this is a good (general
> and portable) solution either.

Well, R_GetCCallable hides all these details for you.

> How can this issue be addressed? How can I solve the problem of linking to
> another package's library (if possible by just using "LinkingTo")

Hmm, it has been addressed and there are working examples (on CRAN and 
BioC).  However, there is another approach possible on Windows _only_ that 
seems close to what you are asking for.

On Windows there are two issues, compilation and run-time.  The run-time 
issue is easy to solve using the Dllpath argument to library.dynam (and 
that is the bit that cannot be done portably across OSes).  The 
compilation-time issue can be addressed in many ways, but perhaps the 
simplest is to make in package rcom an import library for rscproxy.dll

The main problem with the CRAN version of rcom is that rproxy.h is 
missing.  If I copy that file from the 2.7.2 sources and alter 
rcom/src/Makevars to have

PKG_LIBS = -L. -lrscproxy $(ADD_LIBS) -lole32 -luuid -loleaut32 -lgdi32
DLLTOOLFLAGS=--as $(AS)

before: librscproxy.dll.a
librscproxy.dll.a: rscproxy.def

with

$ cat rcom/src/rscproxy.def
LIBRARY rscproxy.dll
EXPORTS
  ANSI2BSTR
  BDX2SEXP
  BDX2Variant at 8
  BSTR2ANSI
  R_Proxy_printf
  SEXP2BDX
  Variant2BDX at 20
  bdx_free at 4
  com_addObject
  com_createSEXP
  com_getHandle
  com_getOLECHAR
  com_getObject

this installs for me (and I always install to a non-default library).

I then removed the useDynLib call in NAMESPACE and added in .onLoad

     toRscproxy <- system.file("libs", package="rscproxy")
     library.dynam("rcom", pkg, lib, Dllpath=toRscproxy)

but I am not sure that is needed if rscproxy.dll is already loaded into 
the process.

An alternative is to run R at install time and ask it to print out 
system.file("libs", package="rscproxy"), in a similar way to finding the 
'LinkingTo' paths.

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] LinkingTo on Windows
Prof Brian Ripley