我正在使用 NDK 开发 OpenCV 项目。还有一些对 OpenCV 库的 Java 调用。java 调用当前工作正常,项目编译并运行良好。然而,一旦引入本机调用,应用程序就会崩溃,然后错误出现在引用的 .cpp 文件中,说明could not be resolved
错误(例如Symbol 'cv' could not be resolved
)。在打开 cpp 文件之前,似乎没有错误,这就是应用程序最初运行的方式。每次 Eclipse 重新启动时,错误才会出现,直到如前所述触发。
我事先在 OpenCV 提供的样本之一(即样本 3 - 本机)上测试了 cpp 文件,并且工作正常,因此它必须位于链接过程中的某个位置。
项目物业详情及问题研究
在扫描并比较当前有问题的项目的项目设置和成功运行的OpenCV的示例之后;我注意到的差异是:
项目
Current ToolChain
(在项目属性中C/C++ Build
>下)是,而 OpenCV 的示例是. 我记得在某处读到这是推荐设置,但不确定为什么,但在将我的 Android 项目转换为 C/C++ 项目的早期,我不记得找到可调整的工具链选项。Tool Chain Editor
Cygwin GCC
No ToolChain
有问题的
Configuration
项目中的 是Debug [Active]
,而 OpenCV 示例中的是Default [Active]
.Configuration
我在项目的下拉菜单中找不到后者作为选项。(indexer build configuration
UnderC/C++ General
>Indexer
) 反过来在我的项目有的地方也不同Debug
,而 OpenCV 的示例有Default
.
下面说明了我的项目的上述设置(不是 OpenCV 的示例):
工具链编辑器设置
索引器构建配置设置
该项目准备了推荐的建议,这些建议可以在大多数教程和有关此事的问题中找到;作为添加必要的项目路径和添加NDKROOT
路径(也提到这里)。该ndk-build
命令也已成功运行。
此外,cpp 文件中的方法名称被命名为我在 OpenCV 示例中观察到的命名约定,即它遵循这种模式;Java_packageName_callingJavaClass_functionName
.
代码和详细结果
下面是Android.mk
大纲:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=on
include <Full Path To OpenCV>\OpenCV\sdk\native\jni\OpenCV.mk
LOCAL_MODULE := proc #The name referred to in System.loadLibrary() in the calling Android activity
LOCAL_SRC_FILES := proc.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
Application.mk
如下:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi
编辑下面是第一次运行的 logcat 输出(之后,编译错误,即以could not be resolved
错误的形式,在 cpp 中实现,因此除非重新启动 Eclipse,否则无法运行)。median
是发生崩溃时调用的本机方法。
01-29 19:14:23.786: W/dalvikvm(8750): No implementation found for native Lcom/ocv/MainActivity;.median (JJ)V
01-29 19:14:23.786: W/dalvikvm(8750): threadid=1: thread exiting with uncaught exception (group=0x400207d8)
01-29 19:14:23.786: E/AndroidRuntime(8750): FATAL EXCEPTION: main
01-29 19:14:23.786: E/AndroidRuntime(8750): java.lang.UnsatisfiedLinkError: median
01-29 19:14:23.786: E/AndroidRuntime(8750): at com.ocv.MainActivity.median(Native Method)
01-29 19:14:23.786: E/AndroidRuntime(8750): at com.ocv.MainActivity.onActivityResult(MainActivity.java:155)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.Activity.dispatchActivityResult(Activity.java:3890)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.ActivityThread.deliverResults(ActivityThread.java:3517)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3563)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.ActivityThread.access$2800(ActivityThread.java:126)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2068)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.os.Handler.dispatchMessage(Handler.java:99)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.os.Looper.loop(Looper.java:123)
01-29 19:14:23.786: E/AndroidRuntime(8750): at android.app.ActivityThread.main(ActivityThread.java:4633)
01-29 19:14:23.786: E/AndroidRuntime(8750): at java.lang.reflect.Method.invokeNative(Native Method)
01-29 19:14:23.786: E/AndroidRuntime(8750): at java.lang.reflect.Method.invoke(Method.java:521)
01-29 19:14:23.786: E/AndroidRuntime(8750): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
01-29 19:14:23.786: E/AndroidRuntime(8750): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-29 19:14:23.786: E/AndroidRuntime(8750): at dalvik.system.NativeStart.main(Native Method)
编辑
关于使用的代码;对于.java 活动代码,即MainActivity.java
,下面是与本机功能相关的摘录。
// package name
package com.ocv;
// Class header
public class MainActivity extends Activity implements View.OnClickListener{
// native method declaration
public native void median(long matAddrGr, long matAddrRgba);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (OpenCVLoader.initDebug()){
/* This is line 155 referenced from logcat */
median(gray_img.getNativeObjAddr(), rgb_img.getNativeObjAddr());
}
}
}
关于本机代码,proc.cpp
(遵循与从 OpenCV 示例中理解的类似模式):
#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <vector>
using namespace std;
using namespace cv;
extern "C" {
JNIEXPORT void JNICALL Java_com_ocv_MainActivity_median(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)
{
Mat* pMatGr=(Mat*)addrGray;
Mat* pMatRgb=(Mat*)addrRgba;
vector<KeyPoint> v;
medianBlur(*pMatGr,*pMatRgb,3);
}
}
关于库加载;OpenCV 已成功加载(在本机 cpp 文件出现错误之前的第一次运行中),如下所示(我什至在调用本机方法之前Imgproc.cvtColor
在 Java 中成功调用(在活动中) ): MainActivity.java
median
导致的语义错误proc.cpp
:
问题
上述项目属性的观察是否可能与问题相关?如果可以,如何修改?如果没有,知道可能导致错误的原因是什么吗?
我正在使用 Eclipse Indigo Service Release 2(因此这个对 Eclipse Juno 用户的解决方案不适用)。
我在网上发现了很多类似的问题(其中一些是前面链接的);但到目前为止,建议的答案似乎都没有解决这个问题。
先感谢您。