gpt4 book ai didi

带有外部库的 Java JNI 'C' 代码

转载 作者:太空宇宙 更新时间:2023-11-04 02:45:40 27 4
gpt4 key购买 nike

我已遵循本指南 Beginning JNI with NetBeans IDE and C/C++ Plugin on Linux从我的 Java 应用程序运行“C”代码,一切正常。

我的问题是当我尝试使用外部库(如 amqp.h)时出现错误:

symbol lookup error: /home/amir/NetBeansProjects/c_pcap_parser/lib/c_pcap_parser.so: undefined symbol: amqp_new_connection Java Result: 127

如何将这些库包含在我的最终 .so 文件中?

最佳答案

首先,您应该对平台上的原生库有一个基本的了解。有静态库和动态库。

静态是指所有的原生代码都被添加到一个库文件中,以供重用。因此,如果您已经编译了一些 C 代码,您就会知道 *.o 文件,其中包含您的处理器可以理解的二进制代码。静态库只是它们的集合。它们在 Linux 平台上通常具有文件扩展名 .a。链接到静态库时,所有 native 二进制代码都将添加到您的应用程序(假设是您的可执行文件)。

相比之下,动态库不会物理添加到您的可执行文件中,如果需要,它将从全局系统目录中引用(这类似于 PATH 环境)。它们在 linux 上被称为共享对象(扩展名为 .so)。在大多数平台上还有一个环境变量,我认为它称为 LD_LIBRARY_PATH(请参阅 this 堆栈溢出以获得目标)。将搜索环境变量的所有目录以查找可以在启动时链接到您的应用程序的共享对象。

好的,考虑到这一点,您可以尝试解决问题。我想 amqp.h 属于 C rabbitmq client .如果你想在java中使用那个c代码,你需要先在你的平台上编译它。这是按照我上面引用的 github 项目页面上的描述完成的。

好的,在成功构建过程之后,您将从编译中获得一些库文件,我认为他们会创建一个动态库,但我不确定。此结果的结果决定了您对 java 代码的操作。如果是动态库,将共享对象添加到java原生库路径即可。您引用的教程中也显示了这一点。我刚刚为 rabbitmq c 库的潜在共享对象添加了一个条目:

static {
System.load("full-path-to-NetBeansProjects-dir/JNIDemoCdl/dist/libJNIDemoCdl.so");
System.load("full-path-to-dir-where-the-rabbitmq-so-lives-in/librabbitmq.so");
}

如果它是一个静态库,您实际上需要对此有所不同。您需要在 C 编译期间链接 librabbitmq.a 库才能正确连接。在您的问题中引用的教程中,我看到 Netbeans 有一个用于 C 编译器的链接器部分,您可以在其中在 C 编译期间添加 rabbitmq 的静态库。

一个免责声明:如果您只想使用 Java 代码访问 rabbitmq,那当然也会退出 java library这应该更容易与 rabbitmq 一起使用(你不需要整个 JNI 和 C 编译的东西)。

还有一个关于您问题中给定教程的注释:他们使用 -m32 标志编译 C 代码,生成 32 位共享对象。如果您按照我上面的说明进行操作,这可能是个问题!原因是您还需要使用此标志将 rabbitmq C 客户端编译为 32 位。大多数平台上的默认 gcc 编译器将生成 64 位库,这些库与 32 位 JVM 和您的 32 位共享库不兼容。所以确保所有都是 32 位或 64 位,但无论如何不要混在一起!例如,在 64 位机器上使用 64 位 JVM,您必须删除 -m32 标志。

关于带有外部库的 Java JNI 'C' 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27687031/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com