使用 jni 和 OpenCV 创建的带有 lib 的未定义符号

Posted

技术标签:

【中文标题】使用 jni 和 OpenCV 创建的带有 lib 的未定义符号【英文标题】:undefined symbol with lib created with jni and OpenCV 【发布时间】:2017-05-06 10:02:03 【问题描述】:

我不明白如何创建一个本机方法,该方法采用 Mat 并将其返回修改后。

我在 java 类中有这段代码:

private native void getCanny(long mat);
getCanny(mat.getNativeObjAddr());

以及生成的 Mat2Image.h:

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

#ifndef _Included_Mat2Image
#define _Included_Mat2Image
#ifdef __cplusplus
extern "C" 
#endif
/*
 * Class:     Mat2Image
 * Method:    getCanny
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_Mat2Image_getCanny
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus

#endif
#endif

这是我制作的 .cpp:

#include "Mat2Image.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc.hpp>


JNIEXPORT void JNICALL Java_Mat2Image_getCanny
   (JNIEnv * env, jobject obj, jlong matr)


       cv::Mat* frame=(cv::Mat*)matr;
            cv::cvtColor(*frame, *frame, CV_BGR2GRAY);
            cv::GaussianBlur(*frame, *frame, cv::Size(7,7), 1.5, 1.5);
            cv::Canny(*frame, *frame, 0, 30, 3);



但是当我尝试运行该方法时出现此错误:

/usr/lib/jvm/jdk1.8.0_111/bin/java: symbol lookup error: /home/buzzo/Downloads/helloJni-master/jni/libMat.so: undefined symbol: _ZN2cv8cvtColorERKNS_11_InputArrayERKNS_12_OutputArrayEii

【问题讨论】:

以上到底是什么问题? .cpp 代码不起作用,我不明白如何制作它 好吧,我有点猜到 .cpp 代码不起作用,只是从这个问题首先出现的事实来看。但我们需要更多细节。你期望它做什么?你为什么期望它这样做?它实际上在做什么?如果没有这些详细信息,我们将无法为您提供帮助。 我只是问如何创建一个本地方法来获取一个 Mat 并在 c++ 中返回一个 Mat 并在 java 中使用它 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误必要的最短代码 重现它在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example。另见:Why is "Can someone help me?" not an actual question? 【参考方案1】:

当您构建.so 时,您通常不会将依赖库与它链接。您可以在构建可执行文件时添加它们。并且链接器在构建.so 时不会抱怨缺少符号,但在构建可执行文件时会这样做。

但是,对于 JNI,这不起作用,因为您使用已修复的 java 可执行文件,并且您动态加载库。所以你必须将依赖库链接到你的.so。找出 cvtColor 和其他函数在哪个库中,并查找工具链的链接器选项,以了解您需要如何在命令行上指定它。另请注意,对于大多数链接器,参数的顺序很重要。

【讨论】:

好吧,算了。当我注意到您的其他问题时,我刚刚看到您发现了自己

以上是关于使用 jni 和 OpenCV 创建的带有 lib 的未定义符号的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ OpenCV 中显示带有 putText 的计时器结果?

JNI、NDK 和 OpenCV

使用 JNI 传递和返回 OpenCv Mat 对象

当从属共享库包含符号时 ,Java JNI“符号查找错误”

从 JNI (OpenCV putText) 获取字符串以在 Java 中显示

OpenCV到JNI如何使它工作?