NDKを使用してOpenCVプロジェクトに取り組んでいます。OpenCV のライブラリへの Java 呼び出しもいくつかあります。Java 呼び出しは現在正常に機能しており、プロジェクトは正常にコンパイルおよび実行されます。ただし、ネイティブ コールが導入されると、アプリがクラッシュし、エラーを示す参照先の .cpp ファイルにエラーが表示されcould not be resolved
ます (例: Symbol 'cv' could not be resolved
)。cpp ファイルを開く前は、エラーがないように見えます。これは、アプリが最初に実行された方法です。Eclipseを再起動するたびに、前述のようにトリガーされるまでエラーは表示されません。
OpenCV が提供するサンプルの 1 つ (つまり、サンプル 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
EDIT以下は、最初の実行時の 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 ユーザーに対する このソリューションは適用されません)。
オンラインで同様の質問を多数見つけました (そのうちのいくつかは以前にリンクされています)。しかし、これまでに提案された回答はどれも問題を解決していないようです。
前もって感謝します。