java - 从Java调用C++共享库方法无法找到类方法的定义

标签 java c++ jna

我需要在Debian上从Java调用.so lib函数。我使用以下Java / JNA代码来实现:

interface MyLib extends Library {
    MyLib INSTANCE = (MyLib) Native.loadLibrary("mylib.so", MyLib.class);
    int fff();
}

// ...

MyLib m = MyLib.INSTANCE;
System.out.println(m.fff());
这是我的C++代码:
.h2

class A1
{
   public:
   void f();
};

.cpp2

#include ".h2"

void A1::f()
{
   std::cout << "from A1" << std::endl;
}

.h1
extern "C"
{
   int fff();
}

.cpp1

#include ".h1"
#include ".h2"

int fff()
{
   // A1().f(); // ERROR CODE

   return 38;
}
如果注释了ERROR CODE-一切正常,C++的Java调用成功,我得到“38”。但是,如果没有注释错误代码,则会出现此错误
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x000000000005bb66, pid=14991, tid=14992
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2+13) (build 10.0.2+13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.2+13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  0x000000000005bb66
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/devuser/dev/ktv/tlv/hs_err_pid14991.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Aborted
如果我将A1:: f()的定义放在h2 header 中-一切都还可以。
看来,Java在cpp2文件中找不到A1:: f()定义。为什么?
我是否应该将我的所有代码层次结构(由fff()标记的extern "C"调用)组成?
好吧,我在美眉日志中发现了以下错误:
Event: 0.300 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a96018}: method resolution failed> (0x00000000c5a96018) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.300 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a99b40}: java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(Ljava/lang/Object;Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;> (0x00000000c5a99b40) thrown at [/scratch/opt/mach5/meso
Event: 0.301 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5a9fd60}: method resolution failed> (0x00000000c5a9fd60) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.302 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5aa3708}: method resolution failed> (0x00000000c5aa3708) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.306 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5aadfd0}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;> (0x00000000c5aadfd0) thrown at [/scratch/opt/mach5/mesos/wo
Event: 0.306 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c5ab1e20}: java.lang.invoke.DirectMethodHandle$Holder.invokeSpecial(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;> (0x00000000c5ab1e20) thrown at [/scratch
Event: 0.320 Thread 0x00007f4338011000 Exception <a 'java/lang/UnsatisfiedLinkError'{0x00000000c5916378}: mylib.so: undefined symbol: _ZTVN4Json10FastWriterE> (0x00000000c5916378) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af
Event: 0.324 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c59233d0}: method resolution failed> (0x00000000c59233d0) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-9581-ce26f27e3af4-S497/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-01
Event: 0.327 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c592e328}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)I> (0x00000000c592e328) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/c4ee7e63-1ded-4e8c-958
Event: 0.330 Thread 0x00007f4338011000 Exception <a 'java/lang/NoSuchMethodError'{0x00000000c593b1f8}: java.lang.Object.of([Ljava/lang/Object;)Ljava/util/stream/Stream;> (0x00000000c593b1f8) thrown at [/scratch/opt/mac
我尝试解决错误od undefined symbol_ZTVN4Json10FastWriterE。我有/usr/lib/libjsoncpp.so.0.6.0,它导出了此方法,但是我不能告诉Java得到它:)有我的所有设置:
file /usr/lib/libjsoncpp.so.0.6.0
/usr/lib/libjsoncpp.so.0.6.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=431ec951fde0671c890664dd6f2e18116509a1bc, stripped
...
file mylib.so
mylib.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=756a5666d6e1d1ceb1c77be5c70a31d4698f64af, not stripped
...
java --version
java 14.0.2 2020-07-14
Java(TM) SE Runtime Environment (build 14.0.2+12-46)
Java HotSpot(TM) 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)
...
echo $LD_LIBRARY_PATH
/path_to_mylib_dir:/usr/lib
...
run command
java -Djava.library.path=/usr/lib -Djna.library.path=/usr/lib -jar app-1.0-SNAPSHOT.jar
...
.java
static {
System.setProperty("java.library.path", "/path_to_mylib_dir:/usr/lib");
System.setProperty("jna.library.path", "/path_to_mylib_dir:/usr/lib");
}
..
interface MyLib extends Library {
        MyLib INSTANCE = (MyLib) Native.loadLibrary("/path_to_my_lib/mylib.so", MyLib.class);
        int fff();
    }
..
 MyLib m = MyLib.INSTANCE; -- OK
 System.out.println(m.fff());    -- Crash

调试输出
 sudo java10 -Djava.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Djna.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Dsun.boot.library.path=/usr/lib/libjsoncpp.so.0.6.0 -Djna.debug_load=true  -jar app-1.0-SNAPSHOT.jar mylib.so
Hello4
java lib path : /usr/lib;/usr/lib/libjsoncpp.so.0.6.0
jna lib path : /usr/lib/libjsoncpp.so.0.6.0
start
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Looking in classpath from jdk.internal.loader.ClassLoaders$AppClassLoader@69663380 for /com/sun/jna/linux-x86-64/libjnidispatch.so
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Found library resource at jar:file:/app-1.0-SNAPSHOT.jar!/com/sun/jna/linux-x86-64/libjnidispatch.so
Nov 06, 2020 2:44:58 PM com.sun.jna.Native extractFromResourcePath
INFO: Extracting library to /root/.cache/JNA/temp/jna12671529648887219091.tmp
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Looking for library '/../mylib.so'
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding paths from jna.library.path: /usr/lib/libjsoncpp.so.0.6.0
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying /../mylib.so
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Loading failed with message: /../mylib.so: undefined symbol: _ZTVN4Json10FastWriterE
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding system paths: [/usr/lib/x86_64-linux-gnu, /lib/x86_64-linux-gnu, /lib64, /usr/lib, /lib, /usr/lib/vmware-tools/lib64/libvmGuestLibJava.so, /usr/lib/vmware-tools/lib32/libvmGuestLibJava.so, /usr/lib/vmware-tools/lib64/libvmGuestLib.so, /usr/lib/vmware-tools/lib32/libvmGuestLib.so, /usr/lib/x86_64-linux-gnu/libfakeroot, /usr/lib/vmware-tools/lib64/libDeployPkg.so, /usr/lib/vmware-tools/lib32/libDeployPkg.so]
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying /../mylib.so
Nov 06, 2020 2:44:58 PM com.sun.jna.NativeLibrary loadLibrary
INFO: Found library '/../mylib.so' at /../mylib.so
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000212716, pid=28990, tid=28991
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2+13) (build 10.0.2+13)

And nm for jsoncpp lib
nm -D ./libjsoncpp.so.0.6.0 |grep  _ZTVN4Json10FastWriterE
00000000002430a0 V _ZTVN4Json10FastWriterE

最佳答案

通过编译c++ .so lib并添加到cmakelists.txt中,将undefined必需的静态和共享库添加到target_link_libraries中,即可解决该问题。

关于java - 从Java调用C++共享库方法无法找到类方法的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64701088/

相关文章:

java - 合并两个 flv 视频的最简单方法是什么?

java - 在不向用户显示而是在后面处理的JSP页面中集成sql语句是否可取?

c++ - 为什么派生类中的重写函数会隐藏基类的其他重载?

c++ - 为什么我的代码不起作用?

java - Kotlin:创建并引用真正的 Java 数组(用于 JNA)

java - 禁用 Jtabbedpane 中的选项卡时,该选项卡的外观和感觉没有变化

java - Android 蓝牙第一次连接失败

C++ 获取对象类型

java - 32 位 JRE 中的 jna 指针

java - 减少/缩小使用 JNA 的 Java 项目的 JAR 大小?