java - 为什么它甚至可以编译? - 使用 swig 生成的类从 java 编译和运行 native 方法

标签 java linux java-native-interface shared-libraries swig

所以我关注了this生成 JNI 代理类和共享库的 Swig 教程。结果我得到了 libexmple.so 文件。

Building a Java module教程部分你可以看到。

 $ swig -java example.i
 $ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
 $ gcc -shared example.o  example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias  -o example.dll
 $ cat main.java

 public class main {
       public static void main(String argv[]) {
         System.loadLibrary("example");
         System.out.println(example.getMy_variable());
         System.out.println(example.fact(5));
         System.out.println(example.get_time());
       }
 }

 $ javac main.java
 $ java main
 3.0
 120
 Mon Mar  4 18:20:31  2002

3.0、120 和 Mon Mar 4 18:20:31 2002 是函数结果。

老实说,我什至没想到它会编译,但它确实编译了,而且当我执行 java main. 所以我的第一个问题是? java如何知道println方法调用中的“example”是什么

System.out.println(example.getMy_variable());

当我尝试通过 Intellij IDE 编译它时,自然会抛出一个错误 我应该抛出“找不到符号示例”。

第二次尝试以这种方式使用这个库

public class Main {

static {
    try {
        System.loadLibrary("example");
        System.out.println("lib initialized");
    } catch (Exception e) {
        System.out.println(e.toString());
    }

}

public static native void My_variable_set(double jarg1);

public static native double My_variable_get();

public static native int fact(int jarg1);

public static native int my_mod(int jarg1, int jarg2);

public static native String get_time();

public static void main(String args[]) {
    try {
        Main.fact(3);
        System.out.println("method called successfully");
    } catch (Exception e) {
        System.out.println(e.toString());
    }

}

我得到了

Exception in thread "main" java.lang.UnsatisfiedLinkError: test.Main.fact(I)I

尝试调用 native 方法时。

我确信 lib 已正确加载(获取 lib 初始化日志)。当我尝试加载不存在时出现不同的错误(类加载异常)

java.lang.UnsatisfiedLinkError: no exampleld in java.library.path

最佳答案

为什么它甚至可以编译?

因为 javac 可以看到 ma​​in 使用同一个 package 中的类 example,并编译它。实际上,它还找到了 exampleJNI 类,它也是由 swig 自动生成的,并在 example.java 中使用。

java 如何知道 println 方法调用中的“example”是什么?

在 Java 中,对于同一包中的类,您不需要import,这就是 java 知道如何调用 example.getMy_variable().

当我尝试使用这个库时,出现异常

您尝试将 native 方法从 exampleJNI.java 移动到 ma​​in.java 失败,因为对于 JNI,类的名称用于确定 native 功能。如果查看 example.dll 的导出函数列表,您可以看到它。

如果您想使用swig,只需使用它生成的文件即可。如果您想更好地了解 JNI 的工作原理,请阅读书籍或在线文档,遵循教程等。不要尝试将 swig 用于它不是的东西:JNI 编程介绍。

关于java - 为什么它甚至可以编译? - 使用 swig 生成的类从 java 编译和运行 native 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47025029/

相关文章:

java - Selenium 元素不可点击问题

java - 在 Java 中使用枚举有什么好处?

java - 引用对象的实例变量

linux - Sox:混合两个输入,其中一个重复

linux - libpcap setfilter() 函数和丢包

java - 将 native (C) 指针保存到对象实例中——然后清理它

java - Java 中基于代理的建模 - 动画问题

linux - 链接器无法找到 curl_global_init

java - 获取有关新窗口打开的信息

java - 为什么我的程序会抛出此 JNI 错误?