I'm working on an OpenCV project, using NDK. There are also some Java calls to OpenCV's library. The java calls are currently working fine, and the project compiles and runs fine. Once a native call is introduced however, the app crashes and then errors appear in the .cpp file referenced stating the could not be resolved
error (for eg. Symbol 'cv' could not be resolved
). Before opening the cpp file, there seem to be no errors, which is how the app is run initially. With every Eclipse restart, the errors don't appear until triggered as mentioned.
I've tested the cpp file beforehand on one of the OpenCV's provided samples (namely; sample 3 - native), and was working fine, so it must be somewhere in the linking process.
Project properties details& problem research
After scanning through and comparing the project settings of the current project in question and the successfully running OpenCV's sample; the differences I noticed were:
The project's
Current ToolChain
(underC/C++ Build
>Tool Chain Editor
,in the project's properties) isCygwin GCC
, while OpenCV's sample isNo ToolChain
. I recall reading somewhere that this is a recommended setting, unsure why, but early when converting my Android project to a C/C++ project, I don't recall finding the tool chain option as adjustable.The
Configuration
in the project in question isDebug [Active]
while that in the OpenCV sample isDefault [Active]
. I couldn't find the latter as an option in theConfiguration
drop-down menu in my project. Theindexer build configuration
(UnderC/C++ General
>Indexer
) in turn is also different where my project hasDebug
, and OpenCV's sample hasDefault
.
Below illustrates my project's aforementioned settings (not OpenCV's sample):
Tool Chain Editor settings
Indexer Build Configuration settings
The project is prepared with the recommended suggestions that can be found in most tutorials and in questions regarding the matter; as adding necessary project paths and adding the NDKROOT
path (also mentioned here). Also the ndk-build
command has run successfully.
Also, the method names in the cpp file are named as the naming convention that I've observed in the OpenCV sample, namely it follows this pattern; Java_packageName_callingJavaClass_functionName
.
Code and detailed results
Below is the Android.mk
outline:
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
is as follows:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi
EDIT Below is the logcat output for the first run (afterwards, compile errors, namely in the form of could not be resolved
errors, in the cpp are realised and thus no run is possible unless Eclipse is restarted). median
is the native method called upon which the crash occurs.
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)
EDIT
Regarding the code used; for the .java activity code, namely MainActivity.java
, below are excerpts relevant to the native functionality.
// 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());
}
}
}
Regarding the native code, proc.cpp
(following a similar pattern to that understood from OpenCV's samples):
#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);
}
}
Regarding the library loading; OpenCV has successfully loaded (in the first run before the native cpp file's errors appear) as seen below (I even called Imgproc.cvtColor
successfully in Java (in the activity MainActivity.java
) before the native method median
was called):
The semantic errors resulting from proc.cpp
:
Question
Are the above project properties' observations possibly relevant to the problem? How can they be amended if so? If not, any idea what might be causing the error?
I'm using Eclipse Indigo Service Release 2 (and thus this solution to Eclipse Juno users is not applicable).
I've found many similar questions online (some of which are linked earlier); but none of the suggested answers thus far seem to resolve the issue.
Thank you in advance.