【发布时间】:2016-10-03 23:45:29
【问题描述】:
我在使用 System.loadLibrary("") 从 Java 加载静态编译库时遇到问题,但我可以将它作为动态编译库加载(当我以这种方式构建时)就可以了。我正在使用 JDK 8,我的理解是,如果您在 *.cpp 和 *.h 文件中提供 JNI_OnLoad_L,它可以通过 System.loadLibrary("") 加载静态库。
我的 kdu_jni.h 有:
extern "C"
JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *, void *);
我的 kdu_jni.cpp 有:
JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *vm, void *reserved)
{
return JNI_VERSION_1_8;
}
当我尝试使用已编译版本运行时,我的 java.library.path 目录中有 libkdu_jni.a 文件。当我尝试动态加载它时,它与同一目录中的 libkdu_jni.so 文件一起工作正常。尝试使用静态文件 (libkdu_jni.a) 时,我得到:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no kdu_jni in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
在尝试加载 .a 文件之前,我已取出 .so 文件。
我不确定我做错了什么。我认为它甚至没有看到 libkdu_jni.a 文件的 JNI_OnLoad_kdu_1jni() 因为我在其中放置了一个异常并且我没有看到它被抛出。我已经对该名称进行了多次迭代:JNI_OnLoad_kdu_jni()、JNI_OnLoad_kdu_1jni()、JNI_OnLoad() 等。
有什么想法吗?
【问题讨论】:
-
JNI_OnLoad_kdu_1jni 的定义是否包裹在
extern "C"中?我建议尝试的唯一另一件事是将库命名为简单的名称,例如“L.a”。 -
您无法加载静态编译的库。您必须将它们链接到 .so 或 .dll 中。你的问题没有意义。
-
@EJP Java8 现在支持加载静态库。我正要插话你的评论,但 JEP 178 改变了一切。
-
@EdwinBuck 不可能。静态库被设计为链接器的输入,而不是可执行文件。例如,不解析库内引用。 JEP 178 中描述的是一个库静态链接到 JVM。。链接步骤仍然必不可少。
-
我找不到很好的解释,但我相信这通常不起作用:见here。
标签: java c++ java-native-interface