线程"main" java.lang.UnsatisfiedLinkError 中的异常

Exception in thread "main" java.lang.UnsatisfiedLinkError

本文关键字:异常 UnsatisfiedLinkError lang main java 线程      更新时间:2023-10-16

当我在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 definedn");
#else
    printf("__cplusplus is NOT definedn");
#endif
    return;
}

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

当javah创建头文件时,每个函数的名称类似于Java_package_Class_method。奇怪的是,当这样编译时,JNI无法为本机方法找到合适的函数,并会抛出错误,但如果在Java之前添加下划线,那么JNI就能找到该函数。

如果你用C++编译,你必须用extern "C"包装你的JNI方法,以确保编译器不会应用它自己的mangling:

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

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