Java本机接口错误:无法在AMD 64位平台

时间:2016-06-07 14:42:01

标签: java c dll java-native-interface mingw

我开始学习如何使用JNI。我正在使用JNI here制作Hello World的基本指令集。我有以下文件:

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
           }

     }

通过从命令行运行javah HelloJNI来生成以下头文件:

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

最后我有C代码:

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;
    }

我使用MinGW将C代码编译成Windows中的.dll,如下所示:

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

它编译得很好,但是当我尝试运行java代码java HelloJNI

我收到以下错误:

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)

我假设我需要更改如何使用MinGW编译.dll,因为似乎存在32位/ 64位不匹配。除了使用64位dll之外,我还没有找到任何其他内容,因为我现在正在尝试编译它。我是否必须切换到32位java或者有没有办法以不同的方式编译dll?

1 个答案:

答案 0 :(得分:3)

确实发生了这种情况,因为你有一个32位的DLL而你使用的是64位Java。

本机库和您正在使用的JVM的“位数”必须匹配。您唯一的选择是将DLL编译为64位,或使用32位Java。没有办法让64位Java加载32位DLL。

请参阅示例this question,了解如何在MinGW上使用gcc编译64位DLL。最简单的方法是在编译DLL时使用-m64开关。