Reputation: 1748
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.
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
(under C/C++ Build
> Tool Chain Editor
,in the project's properties) is Cygwin GCC
, while OpenCV's sample is No 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 is Debug [Active]
while that in the OpenCV sample is Default [Active]
. I couldn't find the latter as an option in the Configuration
drop-down menu in my project. The indexer build configuration
(Under C/C++ General
> Indexer
) in turn is also different where my project has Debug
, and OpenCV's sample has Default
.
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
.
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
:
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.
Upvotes: 2
Views: 4887
Reputation: 1
However, someone said, it's a bug of eclipse that eclipse has difficult when include headers.
Upvotes: 0
Reputation: 4525
Upvotes: 1
Reputation: 37
When I had a similar problem I had to change this directory
${ProjDirPath}/../../sdk/native/jni/include
with this one
${ProjDirPath}/../OpenCV-2.4.3.2-android-sdk/sdk/native/jni/include
Upvotes: 0