gcc-mingw is a version of cygwin gcc that can compile directly to the w32 api, without any of the cygwin emulation layer.
% gcc -dumpspecs | sed s%dllcrt2%/lib/mingw/dllcrt2%g > specs.new
% gcc -mno-cygwin -D_REENTRANT -D_GNU_SOURCE \
-D__int64="long long" -D_JNI_IMPLEMENTATION \
-o
-shared -Wl,--kill-at -specs specs.new -L /lib/mingw
The
-mno-cygwin
flag tells the compiler to run in mingw mode, i.e. omit all the cygwin unix compatibility layer and compile directly against the w32 api. GCC's built-in 64-bit type is
long long
, so we map the type used in the JNI headers, __int64
, to that type. Defining _JNI_IMPLEMENTATION
ensures the JNI implementation exports its native method declarations.Defining _REENTRANT and _GNU_SOURCE cause certain additional declarations of C library functions to be included. If you've never heard of them, most likely you don't need them.
The
--kill-at
flag to the linker ensures all symbols are exported undecorated, i.e. _my_func
instead of _my_func@NN
, which is the default when a function is declared as __stdcall
. You could also use --add-stdcall-alias
, which includes both versions of the symbol.The GCC specs need tweaking or gcc-mingw doesn't find its initialization code for dlls,
dllcrt2.o
. We also have to nudge gcc-mingw to find the mingw libraries. Normally this is taken care of automatically by gcc, but for some reason my installation of cygwin gcc wouldn't find them, and no amount of -L or explicit object linkage would fix it.Anyhow, with that out of the way, you don't have to have Microsoft's tools to build JNA or any other JNI library on w32.
I have noted that GCC apparently handles floating point a little differently, since the JNA tests that use FP return values/arguments are failing with the GCC-build dll.
4 comments:
thank you for your blog. I successfully built C dll
and used it with JNA. But I prefer using C++ so I changed from gcc to g++. dll is still generated but
JNA cannot find the procedure defined in dll.
C++ by default mangles the exported function names. You need to place 'extern "C"' before any function you which to export without name mangling.
excellent information. The linker option "-Wl,--kill-at" is essential to avoid the UnsatisfiedLinkError Java exception because the built dll does not have the undecorated name of your C routine. That's a week of development time wasted finding THAT one. gl
Thank you. This was a very helpful article that saved me a lot of time!
Post a Comment