2

我正在使用 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 EditorCygwin GCCNo ToolChain

  • 有问题的Configuration项目中的 是Debug [Active],而 OpenCV 示例中的是Default [Active]. Configuration我在项目的下拉菜单中找不到后者作为选项。( indexer build configurationUnder C/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.javamedian

成功加载 OpenCV,如 logcat 所示

导致的语义错误proc.cpp

cpp 语义错误


问题

上述项目属性的观察是否可能与问题相关?如果可以,如何修改?如果没有,知道可能导致错误的原因是什么吗?

我正在使用 Eclipse Indigo Service Release 2(因此这个对 Eclipse Juno 用户的解决方案不适用)。

我在网上发现了很多类似的问题(其中一些是前面链接的);但到目前为止,建议的答案似乎都没有解决这个问题。

先感谢您。

4

3 回答 3

1
  1. cd 到 jni 目录时,尝试使用 ndk-build 在命令行中构建它。
  2. 如果它构建,关闭所有 cpp 编辑器窗口,重新启动 Eclipse 但不要打开任何 cpp 文件。将您的应用程序作为 Android 应用程序运行。
  3. 如果运行正常,打开 cpp 文件 - 这次你会看到一个错误。
  4. 擦除并重新键入所有“使用命名空间”字符串。我知道这听起来很奇怪,但是当您再次重新启动 Eclipse 时,错误应该会消失。当然,鉴于您的所有路径都是正确的。
  5. 关于包含的警告仍然存在。我不知道为什么,但手机上的安装有效。
于 2013-09-19T23:58:32.967 回答
0

当我遇到类似问题时,我不得不更改此目录

${ProjDirPath}/../../sdk/native/jni/include

有了这个

${ProjDirPath}/../OpenCV-2.4.3.2-android-sdk/sdk/native/jni/include

于 2013-01-30T07:18:02.260 回答
0

这可能很有用。

但是,有人说,eclipse在包含头文件时很难做到,这是eclipse的一个bug。

于 2015-04-21T18:15:50.243 回答