【问题标题】:Exception in thread "main" java.lang.UnsatisfiedLinkError线程“主”java.lang.UnsatisfiedLinkError 中的异常
【发布时间】:2020-07-31 22:08:26
【问题描述】:

当我在 Java 中测试 JNI 时出现以下显式错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Italk2learn.hello()V
    at Italk2learn.hello(Native Method)
    at Italk2learn.main(Italk2learn.java:10)

dll或路径没有问题,因为我的java类的静态代码运行良好:

static {
        try {
            System.loadLibrary("Italk2learn");
        } catch (Exception e) {
            System.err.println(e);
            System.exit(1);
        }
    }

而且我认为它使图书馆很好。

我使用 JVM 32 位编译并获取 C++ 头文件 (javah) 和用于 C++ 的 MinGW32。在这两种情况下,我都将 eclipse 用于 C++ 和 Java。

这是我的代码:

Java:

public class Italk2learn {

    public native void hello();

    public static void main(String[] args) {
        System.out.println("Hello World Java!");
        try {
            new Italk2learn().hello();
        } catch (Exception e) {
            System.err.println(e);
            System.exit(1);
        }
    }
    static {
        try {
            System.loadLibrary("Italk2learn");
        } catch (Exception e) {
            System.err.println(e);
            System.exit(1);
        }
    }
}

C++:

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

JNIEXPORT void JNICALL Java_Italk2learn_hello(JNIEnv *, jobject) {
    printf("Hello World C++!\n");
#ifdef __cplusplus
    printf("__cplusplus is defined\n");
#else
    printf("__cplusplus is NOT defined\n");
#endif
    return;
}

【问题讨论】:

  • 您是如何构建 DLL 的?如果您查看 Italk2learn.DLL 它有多大,它在您的 PATH 中吗?
  • 我在 Eclipse 中使用 GCC C++ 编译器。大小为 75 KB(包括 MinGW 和 JNI),是的,它在我的环境变量的 windows 路径中。

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


【解决方案1】:

我找到了答案!似乎在 Windows 中使用 JNI 时,它会查找以 _Java_ 开头的函数,而在其他所有平台中,它都会查找 Java_。为什么会这样,而不是写在我不知道的文档中,但它使一切工作完美!

当 javah 创建头文件时,每个函数都被命名为 Java_package_Class_method。奇怪的是,当这样编译时,JNI 无法为本地方法找到正确的函数并吐出错误,但如果在 Java 之前添加下划线,那么 JNI 将能够找到该函数。

【讨论】:

    【解决方案2】:

    如果您使用 C++ 进行编译,则必须使用 extern "C" 包装您的 JNI 方法,以确保编译器不会应用自己的修改:

    extern "C" {
        JNIEXPORT void JNICALL Java_Italk2learn_hello(JNIEnv *, jobject) {
            // ..
        }
    }
    

    见:http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp224

    【讨论】:

    • javah 已经在生成到 .h 文件的声明中执行此操作,并且在 .cpp 文件中包含 .h 文件会将其应用于声明中的定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多