【问题标题】:Java JNI “symbol lookup error” when a dependent shared library contains the symbol当依赖共享库包含符号时​​,Java JNI “符号查找错误”
【发布时间】:2018-06-14 18:58:38
【问题描述】:

在 Ubuntu 16.04 上,我正在针对另一个共享库构建一个 JNI 库。依赖是 OpenCv,版本 3.4.0,本地构建,未安装在标准库路径中。

我正在使用来自 maven 的 cmake 来构建我的 JNI 库。编译和链接行的输出如下:

[ 66%] 构建 CXX 对象 CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o /usr/bin/c++ -DUNIX -Dlib_image_native_jiminger_com_EXPORTS -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I /home/jim/src/opencv-packaging/package-native/target/cmake -I/home/jim/utils/opencv-3.4.0/installed/include -fPIC -std=gnu++11 -o CMakeFiles/lib -image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -c /home/jim/src/opencv-packaging/package-native/target/sources/sources/CvRasterNative.cpp [100%] 链接 CXX 共享模块 liblib-image-native.jiminger.com.so /home/jim/src/opencv-packaging/package-native/target/dependency/cmake/bin/cmake -E cmake_link_script CMakeFiles/lib-image-native.jiminger.com.dir/link.txt --verbose=1 /usr/bin/c++ -fPIC -shared -o liblib-image-native.jiminger.com.so CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -Wl,-rpath, /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server /usr/lib/jvm/ java-8-openjdk-amd64/jre/lib/amd64/libjawt.so /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so

当我运行一个调用我的本机函数的测试时,我得到:

.../java: symbol lookup error: [path to my library].so: undefined symbol: _ZN2cv6String8allocateEm

在我的 java 代码中,我明确地加载了这个库(使用 System.load)以及依赖的 OpenCv 库。该符号在我明确 System.load'ing 的 OpenCv 库中。

nm [path to opencv shared library].so | grep _ZN2cv6String8allocateEm

给予

0000000000442990 t _ZN2cv6String8allocateEm

当我调用我的库时,我得到了那个错误。它说符号未定义。但它的定义在我明确加载的另一个库中(注意,它在“文本”段中)。

谁能告诉我我错过了什么?

谢谢

编辑:如果它有所作为,当我 ldd 我的共享库时,我会得到

linux-vdso.so.1 =>  (0x00007ffe6e58f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7d279dc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7d277c5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7d273fb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7d270f2000)
/lib64/ld-linux-x86-64.so.2 (0x00005574eb402000)

【问题讨论】:

  • 您是否更新了LD_LIBRARY_PATH 以包含.so 文件的目录和/或您是否使用-Djava.libary.path 参数运行Java?
  • 我最终尝试了,但我没想到它会起作用。我正在使用完整路径加载文件。我没有使用 System.loadLibrary。我正在调用 System.load(".so 文件的完整路径");每个库。

标签: java c++ linux opencv java-native-interface


【解决方案1】:

我发现了问题所在。我没有意识到nm 命令的输出显示了本地(与外部可见)符号。来自nm 的手册页:

符号类型。至少使用以下类型;其他的也取决于目标文件格式。如果是小写,符号通常是本地的;如果是大写,则符号是全局的(外部的)。

依赖库中的符号是本地的,用小写的't'表示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 2017-08-02
    • 2020-04-13
    • 2021-08-05
    • 2020-01-10
    • 2014-11-12
    相关资源
    最近更新 更多