java - JNI undefined symbol

标签 java c++ java-native-interface

我在从 java (jni) 执行 c 方法时遇到问题。

CMakeLists.txt 的内容如下:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/home/runix/instalers/stasm4.1.0")
set(STASM_DIR ..)
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
 include_directories(${OpenCV_INCLUDE_DIRS})
endif()

find_package(STASM REQUIRED)
if(STASM_FOUND)
  include_directories(${STASM_INCLUDE_DIRS})
endif()

find_package(JNI)
if(JNI_FOUND)
   include_directories(${JNI_INCLUDE_DIRS})
endif()

LINK_DIRECTORIES( ${OpenCV_LIB_DIR} ${STASM_LINK_DIRS} ${JNI_LINK_DIRS})

SET(LIBS ${STASM_LIBRARIES} ${OpenCV_LIBS}  ${JNI_LIBS})

set(CMAKE_CXX_FLAGS "${CMAKE_XX_FLAGS} -fPIC ")
SET(EXECUTABLES minimal)
FOREACH(var ${EXECUTABLES})
add_executable(${var} ${var}.cpp)
target_link_libraries(${var} ${LIBS})
ADD_LIBRARY(ctest SHARED ${var} ${var}.cpp)
ENDFOREACH(var)

代码编译,我可以正确执行可执行文件(正如您在 CMakeLists 中看到的,我生成了动态库和可执行文件)

但是当我尝试从 java 执行代码时它抛出异常:

java -Djava.library.path=. StasmJNI

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/runix/instalers/stasm4.1.0/external/libctest.so: /home/runix/instalers/stasm4.1.0/external/libctest.so: undefined symbol: _ZTVN2cv11_InputArrayE
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1778)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1703)
    at java.lang.Runtime.loadLibrary0(Runtime.java:844)
    at java.lang.System.loadLibrary(System.java:1051)
    at StasmJNI.<clinit>(StasmJNI.java:3)

如果我从 c 函数中删除所有代码,java 可以正常工作,但我不知道问题出在哪里。

Java 代码:

public class StasmJNI {
    static {
        System.loadLibrary("ctest"); /* (2) */
    }

    public StasmJNI() {

    }

    public native float[] getPoints(String path);

    public static void main(String[] args) {
        System.out.println(new StasmJNI().getPoints("Prueba").length);
    }
}

C 代码:

StasmJNI.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class StasmJNI */

#ifndef _Included_StasmJNI
#define _Included_StasmJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     StasmJNI
 * Method:    getPoints
 * Signature: (Ljava/lang/String;)[F
 */
JNIEXPORT jfloatArray JNICALL Java_StasmJNI_getPoints
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

StasmJNI.cpp

#include <stdio.h>
#include <stdlib.h>
#include "opencv/highgui.h"
#include "stasm_lib.h"
#include "StasmJNI.h"

void error(const char* s1, const char* s2)
{
    printf("Stasm version %s: %s %s\n", stasm_VERSION, s1, s2);
    exit(1);
}
using namespace cv;

float* getLandmarks(char * const path, int * size) {

   if (!stasm_init("../data", 0 ))
        error("stasm_init failed: ", stasm_lasterr());

    cv::Mat_<unsigned char> img(cv::imread(path, CV_LOAD_IMAGE_GRAYSCALE));

    if (!img.data)
        error("Cannot load", path);

    if (!stasm_open_image((const char*)img.data, img.cols, img.rows, path,
                          1 , 10 ))
        error("stasm_open_image failed: ", stasm_lasterr());

    int foundface;
    float landmarks[2 * 20];// stasm_NLANDMARKS]; // x,y coords (note the 2)


    int nfaces = 0; 
    int iters  = 0;
    while (iters++ < 2)
    {
        if (!stasm_search_auto(&foundface, landmarks))
             error("stasm_search_auto failed: ", stasm_lasterr());

        if (!foundface)
            break;      // note break

        stasm_force_points_into_image(landmarks, img.cols, img.rows);
        for (int i = 0; i < stasm_NLANDMARKS; i++)
            img(cvRound(landmarks[i*2+1]), cvRound(landmarks[i*2])) = 255;

        nfaces++;
    }
    if(nfaces == 1) 
    *size = stasm_NLANDMARKS * 2;
    else
    *size = 0;
    return landmarks;
}

JNIEXPORT jfloatArray JNICALL Java_StasmJNI_getPoints
  (JNIEnv * env, jobject object, jstring path) {
     int size = 0;
     getLandmarks(path2, &size);
 jfloatArray result;
     result = env->NewFloatArray(size);

return result;
}


int main()
{
    int size = 0;
    CvCapture *capture = cvCaptureFromCAM(0);
    char* const path = "minimal2.jpg";
     IplImage* ipl = cvQueryFrame(capture);
    Mat temp = ipl;
    cv::imwrite(path, temp);
    getLandmarks(path, &size);
    printf("the size %d\n", size);
}

(注意 C++ 代码使用 OPENCV 和 STASM) 提前致谢:)

编辑 1:nm --demangle libctest.so 的输出

0000000000204210 d DW.ref.__gxx_personality_v0
00000000000026be T Java_StasmJNI_getPoints
0000000000203e08 a _DYNAMIC
0000000000203fe8 a _GLOBAL_OFFSET_TABLE_
                 w _Jv_RegisterClasses
                 U _Unwind_Resume@@GCC_3.0
00000000000023cc T getLandmarks(char*, int*)
000000000000238c T error(char const*, char const*)
0000000000002845 W cvRound(double)
000000000000329c r stasm_NLANDMARKS
                 U cv::_InputArray::_InputArray(cv::Mat const&)
000000000000314c W cv::_InputArray::_InputArray<unsigned char>(cv::Mat_<unsigned char> const&)
000000000000314c W cv::_InputArray::_InputArray<unsigned char>(cv::Mat_<unsigned char> const&)
00000000000030c0 W cv::_OutputArray::_OutputArray<unsigned char>(cv::Mat_<unsigned char>&)
00000000000030c0 W cv::_OutputArray::_OutputArray<unsigned char>(cv::Mat_<unsigned char>&)
                 U cv::Mat::deallocate()
0000000000002bde W cv::Mat::MSize::MSize(int*)
0000000000002bde W cv::Mat::MSize::MSize(int*)
0000000000002bf8 W cv::Mat::MStep::MStep()
0000000000002bf8 W cv::Mat::MStep::MStep()
0000000000002c52 W cv::Mat::MStep::operator[](int)
0000000000002b10 W cv::Mat::release()
                 U cv::Mat::copySize(cv::Mat const&)
000000000000287a W cv::Mat::initEmpty()
                 U cv::Mat::Mat(_IplImage const*, bool)
000000000000290a W cv::Mat::Mat()
000000000000290a W cv::Mat::Mat()
0000000000002950 W cv::Mat::~Mat()
0000000000002950 W cv::Mat::~Mat()
0000000000002990 W cv::Mat::operator=(cv::Mat const&)
0000000000002d3a W cv::Mat_<unsigned char>::Mat_(cv::Mat const&)
0000000000002d3a W cv::Mat_<unsigned char>::Mat_(cv::Mat const&)
0000000000002ca2 W cv::Mat_<unsigned char>::~Mat_()
0000000000002ca2 W cv::Mat_<unsigned char>::~Mat_()
0000000000002eb8 W cv::Mat_<unsigned char>::operator=(cv::Mat const&)
0000000000002da2 W cv::Mat_<unsigned char>::operator()(int, int)
00000000000031a2 W cv::Size_<int>::Size_()
00000000000031a2 W cv::Size_<int>::Size_()
                 U cv::imread(std::string const&, int)
                 U cv::imwrite(std::string const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)
                 U cv::fastFree(void*)
0000000000002c74 W JNIEnv_::NewFloatArray(int)
000000000000311c W __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long)
0000000000003198 W __gnu_cxx::new_allocator<int>::new_allocator()
0000000000003198 W __gnu_cxx::new_allocator<int>::new_allocator()
0000000000003112 W __gnu_cxx::new_allocator<int>::~new_allocator()
0000000000003112 W __gnu_cxx::new_allocator<int>::~new_allocator()
0000000000002bb4 W cv::Mat::type() const
0000000000002c30 W cv::Mat::MStep::operator[](int) const
0000000000002bca W cv::Mat::depth() const
                 U cv::Mat::reshape(int, int, int const*) const
                 U cv::Mat::convertTo(cv::_OutputArray const&, int, double, double) const
00000000000030b0 W cv::Mat_<unsigned char>::type() const
                 U std::allocator<char>::allocator()@@GLIBCXX_3.4
                 U std::allocator<char>::~allocator()@@GLIBCXX_3.4
00000000000030f8 W std::allocator<int>::allocator()
00000000000030f8 W std::allocator<int>::allocator()
000000000000303c W std::allocator<int>::~allocator()
000000000000303c W std::allocator<int>::~allocator()
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)@@GLIBCXX_3.4
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@@GLIBCXX_3.4
000000000000313e W void std::_Destroy_aux<true>::__destroy<int*>(int*, int*)
0000000000002ffe W std::_Vector_base<int, std::allocator<int> >::_Vector_impl::_Vector_impl()
0000000000002ffe W std::_Vector_base<int, std::allocator<int> >::_Vector_impl::_Vector_impl()
0000000000002dda W std::_Vector_base<int, std::allocator<int> >::_Vector_impl::~_Vector_impl()
0000000000002dda W std::_Vector_base<int, std::allocator<int> >::_Vector_impl::~_Vector_impl()
0000000000003056 W std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long)
0000000000002e80 W std::_Vector_base<int, std::allocator<int> >::_M_get_Tp_allocator()
0000000000002df4 W std::_Vector_base<int, std::allocator<int> >::_Vector_base()
0000000000002df4 W std::_Vector_base<int, std::allocator<int> >::_Vector_base()
0000000000002e0e W std::_Vector_base<int, std::allocator<int> >::~_Vector_base()
0000000000002e0e W std::_Vector_base<int, std::allocator<int> >::~_Vector_base()
0000000000002cbc W std::vector<int, std::allocator<int> >::vector()
0000000000002cbc W std::vector<int, std::allocator<int> >::vector()
0000000000002cd6 W std::vector<int, std::allocator<int> >::~vector()
0000000000002cd6 W std::vector<int, std::allocator<int> >::~vector()
000000000000308a W void std::_Destroy<int*>(int*, int*)
0000000000002e8e W void std::_Destroy<int*, int>(int*, int*, std::allocator<int>&)
                 U vtable for cv::_InputArray
                 U vtable for cv::_OutputArray
0000000000203e00 d __gthread_active_p()::__gthread_active_ptr
                 U operator delete(void*)@@GLIBCXX_3.4
0000000000203de0 d __CTOR_END__
0000000000203dd8 d __CTOR_LIST__
0000000000203df0 d __DTOR_END__
0000000000203de8 d __DTOR_LIST__
00000000000039b8 r __FRAME_END__
0000000000203df8 d __JCR_END__
0000000000203df8 d __JCR_LIST__
0000000000204218 A __bss_start
                 w __cxa_finalize@@GLIBC_2.2.5
00000000000031d0 t __do_global_ctors_aux
00000000000022e0 t __do_global_dtors_aux
0000000000204208 d __dso_handle
                 w __gmon_start__
                 U __gxx_personality_v0@@CXXABI_1.3
0000000000204218 A _edata
0000000000204228 A _end
0000000000003208 T _fini
0000000000001e80 T _init
00000000000022c0 t call_gmon_start
0000000000204218 b completed.6531
                 U cvCreateCameraCapture
                 U cvQueryFrame
0000000000204220 b dtor_idx.6533
                 U exit@@GLIBC_2.2.5
0000000000002360 t frame_dummy
                 U printf@@GLIBC_2.2.5
                 w pthread_cancel
                 U stasm_VERSION
                 U stasm_force_points_into_image
                 U stasm_init
                 U stasm_lasterr
                 U stasm_open_image
                 U stasm_search_auto

编辑 2:ldd 的输出

linux-vdso.so.1 =>  (0x00007fff693fe000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fd2a639d000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd2a609d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd2a5da0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd2a5b83000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd2a597b000)
libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007fd2a572a000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007fd2a5502000)
libtiff.so.4 => /usr/lib/x86_64-linux-gnu/libtiff.so.4 (0x00007fd2a529e000)
libjasper.so.1 => /usr/lib/x86_64-linux-gnu/libjasper.so.1 (0x00007fd2a5046000)
libv4l1.so.0 => /usr/lib/x86_64-linux-gnu/libv4l1.so.0 (0x00007fd2a4e40000)
libavcodec.so.53 => /usr/lib/x86_64-linux-gnu/libavcodec.so.53 (0x00007fd2a402f000)
libavformat.so.53 => /usr/lib/x86_64-linux-gnu/libavformat.so.53 (0x00007fd2a3d2e000)
libavutil.so.51 => /usr/lib/x86_64-linux-gnu/libavutil.so.51 (0x00007fd2a3b0e000)
libswscale.so.2 => /usr/lib/x86_64-linux-gnu/libswscale.so.2 (0x00007fd2a38c8000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd2a36b1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd2a32f1000)
libv4l2.so.0 => /usr/lib/x86_64-linux-gnu/libv4l2.so.0 (0x00007fd2a30e5000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd2a65d5000)
libvpx.so.1 => /usr/lib/libvpx.so.1 (0x00007fd2a2e3f000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007fd2a2970000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007fd2a2744000)
libtheoraenc.so.1 => /usr/lib/x86_64-linux-gnu/libtheoraenc.so.1 (0x00007fd2a2506000)
libtheoradec.so.1 => /usr/lib/x86_64-linux-gnu/libtheoradec.so.1 (0x00007fd2a22eb000)
libspeex.so.1 => /usr/lib/x86_64-linux-gnu/libspeex.so.1 (0x00007fd2a20d2000)
libschroedinger-1.0.so.0 => /usr/lib/libschroedinger-1.0.so.0 (0x00007fd2a1e1e000)
libgsm.so.1 => /usr/lib/libgsm.so.1 (0x00007fd2a1c10000)
libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x00007fd2a19fa000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007fd2a17e9000)
libv4lconvert.so.0 => /usr/lib/x86_64-linux-gnu/libv4lconvert.so.0 (0x00007fd2a1574000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007fd2a136c000)
liborc-0.4.so.0 => /usr/lib/x86_64-linux-gnu/liborc-0.4.so.0 (0x00007fd2a10f1000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd2a0eed000)

编辑 3:

我加载了 ldd 的输出,但是当加载 ctest 库时程序再次崩溃 带有 undefined symbol :_ZTVN2cv11_InputArrayE。

System.load("/lib/x86_64-linux-gnu/libz.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libstdc++.so.6");
        System.load("/lib/x86_64-linux-gnu/libpthread.so.0");
        System.load("/lib/x86_64-linux-gnu/librt.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libjpeg.so.8");
        System.load("/lib/x86_64-linux-gnu/libpng12.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libtiff.so.4");
        System.load("/usr/lib/x86_64-linux-gnu/libjasper.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0");
        System.load("/lib/x86_64-linux-gnu/libglib-2.0.so.0");
        System.load("/lib/x86_64-linux-gnu/libm.so.6");
        System.load("/lib/x86_64-linux-gnu/libgcc_s.so.1");
        System.load("/lib/x86_64-linux-gnu/libc.so.6");
        System.load("/lib64/ld-linux-x86-64.so.2");
        System.load("/usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libX11.so.6");
        System.load("/usr/lib/x86_64-linux-gnu/libXfixes.so.3");
        System.load("/usr/lib/x86_64-linux-gnu/libatk-1.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libcairo.so.2");
        System.load("/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libfontconfig.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXext.so.6");
        System.load("/usr/lib/x86_64-linux-gnu/libXrender.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXinerama.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXi.so.6");
        System.load("/usr/lib/x86_64-linux-gnu/libXrandr.so.2");
        System.load("/usr/lib/x86_64-linux-gnu/libXcursor.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXcomposite.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXdamage.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libffi.so.6");
        System.load("/lib/x86_64-linux-gnu/libpcre.so.3");
        System.load("/usr/lib/x86_64-linux-gnu/libfreetype.so.6");
        System.load("/usr/lib/x86_64-linux-gnu/libxcb.so.1");
        System.load("/lib/x86_64-linux-gnu/libdl.so.2");
        System.load("/usr/lib/x86_64-linux-gnu/libpixman-1.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libxcb-shm.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libxcb-render.so.0");
        System.load("/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0");
        System.load("/lib/x86_64-linux-gnu/libselinux.so.1");
        System.load("/lib/x86_64-linux-gnu/libresolv.so.2");
        System.load("/lib/x86_64-linux-gnu/libexpat.so.1");
        System.load("/usr/lib/x86_64-linux-gnu/libXau.so.6");
        System.load("/usr/lib/x86_64-linux-gnu/libXdmcp.so.6");
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            //Program crash here
            System.loadLibrary("ctest");

已解决:这是我的解决方案,

先编译成静态库(CMakeLists.txt)

find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
  include_directories(${OpenCV_INCLUDE_DIRS})
endif()

LINK_DIRECTORIES(
  ${OpenCV_LIB_DIR}
)

SET(STASM_BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

SET(OBJ_STASM
${STASM_BASE_DIR}/stasm/asm.cpp
${STASM_BASE_DIR}/stasm/classicdesc.cpp
${STASM_BASE_DIR}/stasm/convshape.cpp
${STASM_BASE_DIR}/stasm/err.cpp
${STASM_BASE_DIR}/stasm/eyedet.cpp
${STASM_BASE_DIR}/stasm/eyedist.cpp
${STASM_BASE_DIR}/stasm/faceroi.cpp
${STASM_BASE_DIR}/stasm/hat.cpp
${STASM_BASE_DIR}/stasm/hatdesc.cpp
${STASM_BASE_DIR}/stasm/landmarks.cpp
${STASM_BASE_DIR}/stasm/misc.cpp
${STASM_BASE_DIR}/stasm/pinstart.cpp
${STASM_BASE_DIR}/stasm/print.cpp
${STASM_BASE_DIR}/stasm/shape17.cpp
${STASM_BASE_DIR}/stasm/shapehacks.cpp
${STASM_BASE_DIR}/stasm/shapemod.cpp
${STASM_BASE_DIR}/stasm/startshape.cpp
${STASM_BASE_DIR}/stasm/stasm.cpp
${STASM_BASE_DIR}/stasm/stasm_lib.cpp
)

SET(OBJ_MOD1
${STASM_BASE_DIR}/stasm/MOD_1/facedet.cpp
${STASM_BASE_DIR}/stasm/MOD_1/initasm.cpp
)

include_directories(${STASM_BASE_DIR}/stasm)
include_directories(${STASM_BASE_DIR}/stasm/MOD_1)

SET(STASM_INCLUDE_DIRS 
${STASM_BASE_DIR}/stasm
${STASM_BASE_DIR}/stasm/MOD_1
)

SET(LIBS  ${OpenCV_LIBS})

set(CMAKE_CXX_FLAGS "${CMAKE_XX_FLAGS} -fPIC ")

set(STASM_LIBS stasm)
add_library(${STASM_LIBS} ${OBJ_MOD1} ${OBJ_STASM})
target_link_libraries(${STASM_LIBS} ${LIBS})


SET(EXECUTABLES minimal minimal2)
FOREACH(var ${EXECUTABLES})
add_executable(${var} apps/${var}.cpp)
target_link_libraries(${var} ${STASM_LIBS} ${LIBS})
ENDFOREACH(var)



#**************************************************************************************************
# Generate batch files for examples
#**************************************************************************************************
#setup Config.cmake
configure_file(STASMConfig.cmake.in
  "${PROJECT_BINARY_DIR}/STASMConfig.cmake" @ONLY)

INSTALL(
FILES ${PROJECT_BINARY_DIR}/STASMConfig.cmake 
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/cmake/ 
COMPONENT dev)

从.a中提取静态库

ar -x static_library_name

编译成共享库

gcc -shared -o libctest2.so minimal.cpp.o -Wl,-rpath,/usr/local/lib/libopencv_calib3d.so/usr/local/lib/libopencv_contrib.so/usr/local/lib/libopencv_core .so/usr/local/lib/libopencv_features2d.so/usr/local/lib/libopencv_flann.so/usr/local/lib/libopencv_gpu.so/usr/local/lib/libopencv_highgui.so/usr/local/lib/libopencv_imgproc .so/usr/local/lib/libopencv_legacy.so/usr/local/lib/libopencv_ml.so/usr/local/lib/libopencv_nonfree.so/usr/local/lib/libopencv_objdetect.so/usr/local/lib/libopencv_photo .so/usr/local/lib/libopencv_stitching.so/usr/local/lib/libopencv_superres.so/usr/local/lib/libopencv_ts.so/usr/local/lib/libopencv_video.so/usr/local/lib/libopencv_videostab .so $PWD/libstasm.so

感谢https://stackoverflow.com/users/1823225/graham-griffiths用户!

最佳答案

Google 快速搜索 _ZTVN2cv11_InputArrayE 显示它应该是库 libopencv_core.so 的一部分 - 在调用 JNI 函数之前,您必须确保它已在 Java 中加载。

因此,在下面添加这一行并确保该库在 Java 可以找到的地方可用:

System.loadLibrary("opencv_core");

编辑:顺便说一下,您可以在 nm 的输出中看到对 _InputArray 的引用,U 表示未定义(如果您在没有 --demangle 选项的情况下运行它,它将打印完全匹配的“损坏”名称它提示的 undefined symbol )。这意味着什么 - 您的代码引用了一些 opencv 类型/函数 - 这些符号在您的库文件中未定义,因此要正常运行它还需要加载 opencv 库文件。

您可能也需要对您的 stasm 库执行相同的操作。

关于java - JNI undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22227696/

相关文章:

Android CMake 使用预构建 .a 库

java - JAXB:编码的 XML 中缺少具体类型信息 (xsi:type)

java - 用于 GWT 的 Moxieapps 文件 uploader 添加多个上传按钮

c++ - 关于 C++ 中默认构造函数的奇怪编译器行为

android - 安卓下"openssl/aes.h: No such file or directory"

java - 从java调用JNI编写的函数而不加载DLL

java - 文本输入字段标签上的助记符

Java : Parse array to positive and negative array

c++ - fstream 从二进制文件末尾删除 N 个字节

java - 处理与 JNI 的关联