Apologies if this has appeared before, but I've searched the archives and all the documentation and I can't find anything which helps.
I'm trying to build a DLL under windows. The process (more on that later) works fine under Linux and gives the illusion of working under Windows, but attempting to load the resulting DLL using dyn.load results in:
Error in inDL(x, as.logical(local), as.logical(now), ...) :
unable to load shared library: 'C:/Documents... '
LoadLibrary failure: Invalid access to memory location.
Searching Google shows that the LoadLibrary message is unique to R (Or no-one else is admitting to it).
The first problem is that the library is actually a wrapper around an existing library to make it usable under R, but the original library is built as a static object (and for reasons of controlling exciting versioning problems, I'd prefer it to stay that way).
Under Linux, I pass the library to gcc using PKG_LIBS=-static lib.a and it builds fine.
Under Windows, I put the following in Makevars.win:
PKG_LIBS -Lc:/Path/To/Library -llib.name
and it builds fine (GCC returns with no errors and I have what appears to be an appropriately sized DLL in the directory).
I've tried passing various flags into gcc, but I really don't know what I'm doing at this point with regard to building under windows (I have a pretty good grasp of how to compile libraries under Linux, and understand the concepts involved in shared libraries. I get the impression however that I'm missing something about Windows DLLs.
Compulsory version information:
OS: Windows XP SP2
R: 2.8.1
GCC: 4.2.1-sjlj (mingw32-2) (From Rtools29.exe)
For the record, I've read http://www.stats.uwo.ca/faculty/murdoch/software/compilingDLLs/readme.packages.txt which hints at some requirement for DLLs to use _cdecl. I've started exploring along this line, but there's a lot of documentation to trawl through to make sense of it all and I don't want to go off chasing a red herring if I just need to pass a special --make-it-work flag to gcc.
In the only thread I found which appeared to have any similarities, Prof. Ripley said that there was a solution (or hint): "It is there, unfortunately along with a lot of uniformed speculation." Of course, the uninformed speculation is still in the archives making it no easier to find no than in August 2007! Perhaps someone who understands this stuff (or has some experience of it) could provide a hint as to how to proceed. :-)
Thanks in advance.
Apologies if this has appeared before, but I've searched the
archives and all the documentation and I can't find anything which
helps.
I'm trying to build a DLL under windows. The process (more on that
later) works fine under Linux and gives the illusion of working
under Windows, but attempting to load the resulting DLL using
dyn.load results in:
Error in inDL(x, as.logical(local), as.logical(now), ...) :
unable to load shared library: 'C:/Documents... '
LoadLibrary failure: Invalid access to memory location.
Searching Google shows that the LoadLibrary message is unique to R
(Or no-one else is admitting to it).
The first problem is that the library is actually a wrapper around
an existing library to make it usable under R, but the original
library is built as a static object (and for reasons of controlling
exciting versioning problems, I'd prefer it to stay that way).
Under Linux, I pass the library to gcc using PKG_LIBS=-static lib.a
and it builds fine.
That is true only for very specific architectures and OS combinations
but not on most systems (including Linux). Shared objects must be
compiled to contain position-independent code (PIC) such that they can
be re-located when loaded dynamically. In general you cannot use a
static library in a package unless the library was specifically
compiled with -fPIC.
Also please note that the above is possibly not what you want: -static
is not an option that applies to the library - it's a global option
for the linker which affects *all* libraries and possibly even the crt
code and compiler-related libraries (this depends on the platform). It
may cause additional problems since you may need to link R library
dynamically. All this is not related to Windows - this applies in
general on any platform (including Linux).
Under Windows, I put the following in Makevars.win:
PKG_LIBS -Lc:/Path/To/Library -llib.name
and it builds fine (GCC returns with no errors and I have what
appears to be an appropriately sized DLL in the directory).
I've tried passing various flags into gcc, but I really don't know
what I'm doing at this point with regard to building under windows
(I have a pretty good grasp of how to compile libraries under Linux,
and understand the concepts involved in shared libraries. I get the
impression however that I'm missing something about Windows DLLs.
See above, this may not be DLL-specific. Additionally, please make
sure you're using the right tools (MinGW gcc) for both your static
library and the package (you have indicated the you do, but just
making sure :))..
I have tested a toy example with your setup and all was working just
fine, so for further help you may have to reveal exactly what library
you are using etc. since the devil may be in the details (if the
general advice above doesn't help).
Compulsory version information:
OS: Windows XP SP2
R: 2.8.1
GCC: 4.2.1-sjlj (mingw32-2) (From Rtools29.exe)
For the record, I've read http://www.stats.uwo.ca/faculty/murdoch/software/compilingDLLs/readme.packages.txt
which hints at some requirement for DLLs to use _cdecl. I've
started exploring along this line, but there's a lot of
documentation to trawl through to make sense of it all and I don't
want to go off chasing a red herring if I just need to pass a
special --make-it-work flag to gcc.
AFAICS that is only mentioned with respect to VC - the current tools
are smart enough with gcc. There are some issues when importing
variables from R itself, but that should not be related to your code
(unless you use this feature outside of the standard R headers).
Cheers,
Simon
In the only thread I found which appeared to have any similarities,
Prof. Ripley said that there was a solution (or hint): "It is there,
unfortunately along with a lot of uniformed speculation." Of course,
the uninformed speculation is still in the archives making it no
easier to find no than in August 2007! Perhaps someone who
understands this stuff (or has some experience of it) could provide
a hint as to how to proceed. :-)
Thanks in advance.
--
Jon Senior <jon at restlesslemon.co.uk>
Simon Urbanek <simon.urbanek at r-project.org> wrote:
That is true only for very specific architectures and OS combinations
but not on most systems (including Linux). Shared objects must be
compiled to contain position-independent code (PIC) such that they can
be re-located when loaded dynamically. In general you cannot use a
static library in a package unless the library was specifically
compiled with -fPIC.
It was indeed compiled with -fPIC on Linux. I had forgotten that and wonder if it might be related.
Also please note that the above is possibly not what you want: -static
is not an option that applies to the library - it's a global option
for the linker which affects *all* libraries and possibly even the crt
code and compiler-related libraries (this depends on the platform). It
may cause additional problems since you may need to link R library
dynamically. All this is not related to Windows - this applies in
general on any platform (including Linux).
AFAICT -static can be used to force inclusion of a library statically. It may not be the case, the bulk of my coding experience is in Java, not wrapping esoteric functions in to R-callable C code! :-) Strangely though, it seems to work fine. I'll have to do some more tinkering to see if it can forced into a single build, rather than a 2-stage one.
See above, this may not be DLL-specific. Additionally, please make
sure you're using the right tools (MinGW gcc) for both your static
library and the package (you have indicated the you do, but just
making sure :))..
Checked and doubled checked. It's a clean installation of XP running under QEMU and has nothing but R and Rtools installed.
I have tested a toy example with your setup and all was working just
fine, so for further help you may have to reveal exactly what library
you are using etc. since the devil may be in the details (if the
general advice above doesn't help).
OK. Since my previous mail, I discovered the pedump tool, and found that both pedump and objdump will segfault (So it appears, Windoze doesn't give enough information to be sure!) if I attempt to retrieve the Ordinal table from the freshly compiled DLL. This suggests that something is going awry during the second stage of the build (since I can retrieve the same information from the .lib file).
The problem with adding more details is the nature of the work. At the minute, I'm obliged to keep the fine details secret. I had a feeling that this might have been the case, but I thought it was worth seeing if someone had already encountered this and solved it in a different specific case.
AFAICS that is only mentioned with respect to VC - the current tools
are smart enough with gcc. There are some issues when importing
variables from R itself, but that should not be related to your code
(unless you use this feature outside of the standard R headers).
OK.
Thanks for your help. Looks like the next step is probably going to be combining both compilation steps into a single Makefile. I really hate Makefiles! :-(