带静态库的JNI:链接错误不满意

时间:2016-05-08 01:00:34

标签: java java-native-interface

我用g ++构建了一个静态库:

g++-5 main.cpp -fPIC -Wall -std=c++11 -lboost_system ......

现在我想通过JNI调用它的方法:

public static void main(String[] args) {
    System.load("/Users/XXX/example/libjnidb4java.a");
    JNIDB db = new JNIDB();
    db.createTable("Name", "Dir");
  }

原来是UnsatisfiedLinkError例外:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/XXX/example/libjnidb4java.a: dlopen(/Users/XXX/example/libjnidb4java.a, 1): no suitable image found.  Did find:
    /Users/XXX/example/libjnidb4java.a: unknown file type, first eight bytes: 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1822)
    at java.lang.Runtime.load0(Runtime.java:809)
    at java.lang.System.load(System.java:1086)

我尝试使用动态库,它工作正常,但在我的情况下,我需要它是静态库。我通过ar -r libjnidb4java.a a.out创建了这个静态库。

我发现Java 8已经支持静态链接库here。就像文档说的那样,我创建了一个方法:

jint JNI_OnLoad_xxxdb4java(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }

1 个答案:

答案 0 :(得分:2)

您无法动态加载静态库。您只能动态加载共享库。

您所参考的JNI文档谈论将JNI与静态库一起使用,但这假设您已将库静态链接到JVM中。因此,如果您真的必须使用静态库,那么您将不得不重建自己的JVM,这听起来像是一种不值得羡慕的体验。

我不清楚为什么在使用静态库和共享库之间存在差异(你仍然试图动态加载它,毕竟,它会向我发送动态库)但我会先尝试克服这个限制。

如果要为用户创建单个可安装单元,那么您需要创建自己的单个共享库。然后,您的库应该静态链接依赖项,以便它们包含在您的库中。然后,您可以在该单元上使用loadLibrary,而无需担心安装依赖项。