1

This question regards a similar problem then JNI %1 is not a valid Win32 application .

I also want to compile a 64 bit static lib from C++ source to use within Java and I also get the error:

Exception in thread "Thread-2" java.lang.UnsatisfiedLinkError: C:\Users\boon\AppData\Local\Temp\keyboardhook-3382807930283923158.lib: %1 is no valid Win32 application at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(Unknown Source) at java.lang.ClassLoader.loadLibrary(Unknown Source) at java.lang.Runtime.load0(Unknown Source) at java.lang.System.load(Unknown Source) at de.ksquared.system.keyboard.Native.load(Native.java:79) at de.ksquared.system.keyboard.KeyboardHook.(KeyboardHook.java:84) at de.ksquared.system.keyboard.PoolHook.run(KeyboardHook.java:51)

whereas I want to compile the KeyboardHook from Kristian Kraljic (http://kra.lc/blog/2011/07/java-global-system-hook/ ) with some added functionality in the library. First I tried to compile my KeyboardHook.cpp with Microsoft Visual Studio 2013 but there the compile flags Kristian suggested were all ignored and I also got the same exception mentioned above. Thus I changed the compiler to MinGW and the compiling is successful with the following command:

g++ -Wall -c -D_JNI_IMPLEMENTATION_ -Wl,-kill-at -O0 -g3 -fmessage-length=0 -static-libgcc -I”%JAVA_HOME%\include” -m64 -I”%JAVA_HOME%\include\win32″ -shared -o keylib.lib KeyboardHook.cpp

most the of flags I took over from Kristians suggestion. The problem seems to be that the generated .lib file seems still not be fully 64bit. The gcc -dumpmachine tells me: x86_64-w64-mingw32, thus both 32bit and 64bit as targets should be possible. With the flag -m64 it should compile with 64 bit however or? I am using the minGW build x64-4.8.1-win32-seh-rev5, Windows 7 64bit and Java7.

I don't know at the moment where else I can find a mistake. Do I have to set the linker flags differently?

Community
  • 1
  • 1
Mike Noon
  • 129
  • 10
  • You need to add `-static-libstdc++` to the flags.. Why? Because if you tried to load your .dll using `LoadLibrary("Myplugin.dll")`, you'll notice it cannot find certain libraries.. Either that or you need to add `Mingw64/bin` to your `%PATH%`. Another thing is to make sure your JVM is 64-bit. So again, try `LoadLibrary` your own plugin from a 64-bit executable and see if it loads.. Then try it with Java after. – Brandon Mar 09 '14 at 14:17
  • You use both `-static-libgcc` and `-shared`? I thought you wanted a static library? – fge Mar 09 '14 at 15:03
  • Can you determine what external symbols your .dll needs using `objdump`? – Mats Petersson Mar 09 '14 at 15:08
  • From the error message, Java is expecting a DLL (a dynamic library) rather than a static library. What are you doing when that error message appears, and why do you think you need a static library? – Harry Johnston Mar 09 '14 at 20:27
  • First of all thanks a lot for all the help. CantChooseUsernames, this got it running now, thanks a million. I added the flag `-static-libstdc++` and the compiling works. About the question dynamic/static library I have to admit I knew too little about it, I am loading the library with `System.load()` once at the beginning of runtime, at the moment a static library (.lib). I guess I can omit the `-shared` then? – Mike Noon Mar 11 '14 at 14:24

1 Answers1

0

In my own project, I use the following flags:

-static-libgcc          # Don't require to ship libgcc_s_seh-1.dll with your dll
-static-libstdc++       # Don't require to ship libstdc++-6.dll
-shared                 # As usual. Yeah, static+shared, Windows is beautiful
-Wl,--add-stdcall-alias # The JVM expects _stdcall decoration while mingw produces
                        #  _cdecl. You could use -Wl,-kill-at but this one is clear
-m64                    # I need 64 bits binary code for my 64 bits JVM

My full code is available on GitHub.

Martin Quinson
  • 1,347
  • 8
  • 16