Skip to content

Problem building DLL under Windows

3 messages · Jon Senior, Simon Urbanek

#
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.
#
Jon,
On Apr 3, 2009, at 10:18 , Jon Senior 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.

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).
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).
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
#
On Fri, 3 Apr 2009 12:36:00 -0400
Simon Urbanek <simon.urbanek at r-project.org> wrote:

            
It was indeed compiled with -fPIC on Linux. I had forgotten that and wonder if it might be related.
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.
Checked and doubled checked. It's a clean installation of XP running under QEMU and has nothing but R and Rtools installed.
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.
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! :-(