I'm trying to create a C dynamic library that's callable from Java. I've compiled a DLL under Cygwin, using SWIG to generate the JNI with the following makefile:
CC= gcc -mno-cygwin
SWIG= /cygdrive/c/Documents\ and\ Settings/student/Desktop/swigwin-2.0.4/swig.exe -java
INCLUDE1= -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_25/include
INCLUDE2= -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_25/include/win32
utilities:
${SWIG} utilities.i
${CC} -c utilities.c utilities_wrap.c ${INCLUDE1} ${INCLUDE2}
${CC} -shared utilities.o utilities_wrap.o -Wl,--add-stdcall-alias -o utilities.dll
Here are the contents of the SWIG interface file utilities.i:
/* utilities.i */
%module utilities
%{
#include "driver.h"
%}
extern int get_3711a_fd(char * device);
/* Other prototypes omitted for brevity */
I've verified that the methods are being correctly exported from the DLL, and placed utilities.dll in both:
- C:\Program Files\Java\jdk1.6.0_25\bin
- C:\Program Files\Java\jdk1.6.0_25\jre\bin
I use System.load(libraryPath)
to load from path 1. above, with the library file-name included in the path, and catch any SecurityException
or UnsatisfiedLinkError
on that call.
The library loads without any exceptions, but calling the library fails with the following:
Exception in thread "main" java.lang.UnsatisfiedLinkError:
invokeoncomport.utilitiesJNI.get_3711a_fd(Ljava/lang/String;)I
at invokeoncomport.utilitiesJNI.get_3711a_fd(Native Method)
at invokeoncomport.utilities.get_3711a_fd(utilities.java:14)
at invokeoncomport.Main.main(Main.java:41)
I found this section of the SWIG documentation, which says:
After looking at
utilities_wrap.c
, I saw my generated JNI method definitions did not contain a package name. To fix this, I added the SWIG -package command-line option to the first line of my makefile:My JNI methods definitions now look like the following, and my linking error is fixed!