2

I'm getting started with learning how to use the JNI. I'm following this basic instruction set on making Hello World with JNI here. I have the following files:

HelloJNI.java

      public class HelloJNI {

           static {
              System.loadLibrary("hello"); //Load native library hello.dll at runtime
           }

           //declare a native method sayHello() w/ no arguments and returns void
           private native void sayHello();

           public static void main(String[] args) {
               new HelloJNI().sayHello(); //invoke the native method
           }

     }

The following header file is machine generated by running javah HelloJNI from the command line:

HelloJNI.h

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloJNI */

    #ifndef _Included_HelloJNI
    #define _Included_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
      * Class:     HelloJNI
      * Method:    sayHello
      * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloJNI_sayHello
      (JNIEnv *, jobject);

    #ifdef __cplusplus
    }
    #endif
    #endif

Finally I have the C code:

HelloJNI.c

    #include <jni.h>
    #include <stdio.h>
    #include "HelloJNI.h"

    JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj){
        printf("Hello World!\n");
        return;
    }

I compile the C code into a .dll in windows using MinGW like so:

gcc -Wl,--add-stdcall-alias -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o hello.dll HelloJNI.c

It compiles fine but when I try to run the java code java HelloJNI

I get the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: E:\Users\Ryan\Repos\HelloJNI\hello.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
    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.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at HelloJNI.<clinit>(HelloJNI.java:4)

I'm assuming that I need to change how to compile the .dll with MinGW since there seems to be a 32 bit/ 64 bit mismatch. I haven't been able to find anything other than use the 64bit dll, which i don't have since I'm trying to compile it right now. Do I have to switch to 32 bit java or is there a way to compile the dll differently?

ryanmattscott
  • 321
  • 5
  • 17

1 Answers1

4

This indeed happens because you have a 32-bit DLL and you are using 64-bit Java.

The "bitness" of the native library and the JVM you are using have to match. The only options you have are compiling the DLL to 64-bit, or use 32-bit Java. There is no way to make 64-bit Java load the 32-bit DLL.

See for example this question on how to compile a 64-bit DLL with gcc on MinGW. The easiest thing to try is to use the -m64 switch when compiling the DLL.

Community
  • 1
  • 1
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • I put the `-m64` flag out front and then i got the following error `HelloJNI.c:1:0: sorry, unimplemented: 64-bit mode not compiled in #include ^` – ryanmattscott Jun 07 '16 at 15:57
  • 1
    @ryanmattscott then the gcc that you are using unfortunately does not support 64-bit, but the question I quoted contains other possible answers. Try [Mingw-w64](http://mingw-w64.org/doku.php) for example, instead of the regular Mingw. – Jesper Jun 07 '16 at 17:36