I wrote a C++ code that compiles in a standard environment. But when I try to translate it towards android shared library, with Swig utility, though I get the source_wrapp.cpp generated, the Android NDK fails to generate the library.
jni/ is the jni subfolder that i created for the purpose (when I remove it -build file for example-, the file is at the choosen project root)
Here is jni/goodComptSolver.h
#include <vector>
#include <string>
#ifndef GOOD_COMPT_SOLVER_H_
#define GOOD_COMPT_SOLVER_H_
class Solutions {
private:
std::vector<std::string> collection;
int maxSize;
public:
Solutions(int size = 5) : maxSize(size) {};
void push_back(const std::string &str);
int size() const;
const std::string& operator[](int index) const; // does not perform index cheching !!!
};
#endif
Here is jni/goodComptSolver.cpp
#include <iostream>
#include "goodComptSolver.h"
using std::cout;
using std::endl;
using std::vector;
using std::string;
void Solutions::push_back(const string &str)
{
if (collection.size() < maxSize)
collection.push_back(str);
}
int Solutions::size() const
{
return collection.size();
}
const string& Solutions::operator[](int index) const
{
return collection[index];
}
Here is jni/goodComptSolver.i
%module goodComptSolver
%rename(bracketOperator) operator[];
%{
#include "goodComptSolver.h"
%}
%include <std_string.i>
%include <std_vector.i>
%template(stringVector) std::vector<std::string>;
%include "goodComptSolver.h"
Here is my build file
swig -c++ -java -package com.loloof64.android_native.good_compt_solver -outdir . -o jni/goodComptSolver_wrap.cpp jni/goodComptSolver.i
echo "-------------------------------------------"
echo "Done with swig"
echo "-------------------------------------------"
ndk-build -B V=1
Here is my jni/Android.mk
# Sets the local path to current dir
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := goodComptSolver
LOCAL_SRC_FILES := goodComptSolver_wrap.cpp goodComptSolver.cpp
LOCAL_CFLAGS := -frtti
include $(BUILD_SHARED_LIBRARY)
Here is jni/Application.mk
APP_ABI := all
APP_STL := gnustl_static
Here is my build output :
$ ./build
-------------------------------------------
Done with swig
-------------------------------------------
rm -f ./libs/armeabi/lib*.so ./libs/armeabi-v7a/lib*.so ./libs/mips/lib*.so ./libs/x86/lib*.so
rm -f ./libs/armeabi/gdbserver ./libs/armeabi-v7a/gdbserver ./libs/mips/gdbserver ./libs/x86/gdbserver
rm -f ./libs/armeabi/gdb.setup ./libs/armeabi-v7a/gdb.setup ./libs/mips/gdb.setup ./libs/x86/gdb.setup
Compile++ thumb : goodComptSolver <= goodComptSolver_wrap.cpp
/home/laurent-bernabe/Programmes/android-ndk-r8e/toolchains/arm-linux-androideabi- 4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi- v7a/objs/goodComptSolver/goodComptSolver_wrap.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 - fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing - finline-limit=64 -I/home/laurent-bernabe/Programmes/android-ndk-r8e/sources/cxx-stl/gnu- libstdc++/4.6/include -I/home/laurent-bernabe/Programmes/android-ndk-r8e/sources/cxx- stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -Ijni -DANDROID -Wa,--noexecstack -frtti -I/home/laurent-bernabe/Programmes/android-ndk-r8e/platforms/android-3/arch-arm/usr/include -c jni/goodComptSolver_wrap.cpp -o ./obj/local/armeabi- v7a/objs/goodComptSolver/goodComptSolver_wrap.o
jni/goodComptSolver_wrap.cpp: In function 'const std::basic_string<char>& std_vector_Sl_std_string_Sg__get(std::vector<std::basic_string<char> >*, int)':
jni/goodComptSolver_wrap.cpp:231:72: error: exception handling disabled, use - fexceptions to enable
jni/goodComptSolver_wrap.cpp: In function '_jstring* Java_com_loloof64_android_1native_good_1compt_1solver_goodComptSolverJNI_stringVector_1get(J NIEnv*, jclass, jlong, jobject, jint)':
jni/goodComptSolver_wrap.cpp:376:73: error: '_e' was not declared in this scope
jni/goodComptSolver_wrap.cpp: In function 'void Java_com_loloof64_android_1native_good_1compt_1solver_goodComptSolverJNI_stringVector_1set(J NIEnv*, jclass, jlong, jobject, jint, jstring)':
jni/goodComptSolver_wrap.cpp:408:73: error: '_e' was not declared in this scope
make: *** [obj/local/armeabi-v7a/objs/goodComptSolver/goodComptSolver_wrap.o] Error 1
I can't post the generated jniCalls file, because it is at least about 400 lines.
I was inspired by this answer in my attempt : and extended in to a vector of string, instead of a native type. But it seems that i misunderstood something : what ?
My environement :
Ubuntu 13.04 64 bits
gcc 4.7.3
Swig 2.0.10
Android NDK recent
Thanks in advance.
Thanks to Chad comment, and a bit of searching in order to understand why, I solved the issue.
The fact is that vector use C++ exceptions, and in order to make them active, I replace, in the Android.mk, the line
LOCAL_CFLAGS := -frtti
with the line
LOCAL_CFLAGS := -frtti -fexceptions
And this time, I had no compilation error.
Related
I have a JNI implementaion of libjpeg-turbo on Android.
Application is built without any problems and I can see inside generated APK file that native libJPEGProcessing.so libraries are inside lib folder for different architectures.
However, when the native method is invoked through application, I will receive the following "no implementation found" message, which will cause the exception:
D/dalvikvm: No JNI_OnLoad found in /system/lib/libjpeg.so 0xa4fe3dc0, skipping init
D/dalvikvm: Trying to load lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: Added shared lib /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0
D/dalvikvm: No JNI_OnLoad found in /data/app-lib/com.google.test-2/libJPEGProcessing.so 0xa4fe3dc0, skipping init
W/dalvikvm: No implementation found for native Lcom/google/test/NativeMethods;.computeUsableDCTCoefficientsLinkedList:(Ljava/lang/String;)I
This is my methods in JNI:
extern "C" {
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
// Register methods with env->RegisterNatives.
return JNI_VERSION_1_6;
}
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *env, jobject obj, jstring javaString)
{
...
}
}
And the generated header file:
extern "C" {
/*
* Class: com_google_test_NativeMethods
* Method: computeUsableDCTCoefficientsLinkedList
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_google_test_NativeMethods_computeUsableDCTCoefficientsLinkedList
(JNIEnv *, jclass, jstring);
}
The implementation in Java looks like this:
package com.google.test;
import java.util.ArrayList;
public class NativeMethods {
private String filename = null;
private int fromNative = -100;
private int numberInList = -100;
private ArrayList<DCTCoefficient> array = null;
static {
System.loadLibrary("jpeg");
System.loadLibrary("JPEGProcessing");
}
public static native int computeUsableDCTCoefficientsLinkedList(String filename);
}
This is Android.mk for ndk-build:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_FILES := ./libjpeg-turbo/
LOCAL_MODULE := JPEGProcessing
LOCAL_CFLAGS := -Ic:\AndroidStudioProjects\Test\Test\src\main\jni\ -Ic:\libjpeg-turbo-gcc\include\
LOCAL_SRC_FILES := JPEGProcessing.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_STATIC_LIBRARIES := c:\libjpeg-turbo-gcc\lib\libjpeg.a
include $(BUILD_SHARED_LIBRARY)
There is no error during building and compiling, application will normally start on Android device. However, I have defined JNI_OnLoad method which is also not called after loading native library in Java class.
EDIT:
I found the following warning in Gradle Console which may be related to it:
Android NDK: WARNING:C:/AndroidStudioProjects/Test/Test/src/main/jni/Android.mk:JPEGProcessing: non-system libraries in linker flags: c:\libjpeg-turbo-gcc\lib\libjpeg.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
EDIT 2:
Trying to see inside the compiled libJPEGProcessing.so on Linux:
nm libJPEGProcessing.so
nm: libJPEGProcessing.so: no symbols
nm -D libJPEGProcessing.so
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002004 A _edata
00002004 A _end
There is no exported JNI methods and symbols. Is this correct?
EDIT 3:
Output of ndk-build.cmd -B V=1 APP_ABI=armeabi:
ndk-build.cmd -B V=1 APP_ABI=armeabi
del /f/q c:\AndroidStudioProjects\Test\Test\src\main\libs\arm64-v8a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi-v7a\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\mips64\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86\libJPEGProcessing.so c:\AndroidStudioProjects\Test\Test\src\main\libs\x86_64\libJPEGProcessing.so >NUL 2>NUL
[armeabi] SharedLibrary : libJPEGProcessing.so
C:/Android/sdk/ndk-bundle/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libJPEGProcessing.so -shared --sysroot=C:/Android/sdk/ndk-bundle/build//../platforms/android-9/arch-arm -lgcc -gcc-toolchain C:/Android/sdk/ndk-bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -no-canonical-prefixes -target armv5te-none-linux-androideabi -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -lc -lm -o c:/AndroidStudioProjects/Test/Test/src/main/obj/local/armeabi/libJPEGProcessing.so
[armeabi] Install : libJPEGProcessing.so => libs/armeabi/libJPEGProcessing.so
copy /b/y "c:\AndroidStudioProjects\Test\Test\src\main\obj\local\armeabi\libJPEGProcessing.so" "c:\AndroidStudioProjects\Test\Test\src\main\libs\armeabi\libJPEGProcessing.so" > NUL
Your code seems ok - I could not see any signature problem, and you seems to be loading the library in the required manner. But, the fact is that the log says the library was found, yet it cannot find your JNI_OnLoad implementation. Is there a chance you have more than one version of libJPEGProcessing.so, and the system finds an older one? I'm not talking about different libraries for the various architectures, of course.
I have found out that although the APK was compiled and working, the native library wasn't correctly compiled and included inside APK file in lib folder.
So I changed build.gradle to not using ndk-build, but instead use pre-compiled native library for the project. After that change, native libraries are included in APK and everything is working:
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set libs as default directory for .so files inclusion, instead of jniLibs
jni.srcDirs = [] //disable automatic ndk-build call
}
The only change I have to do is to compile the native library outside the Android Studio if there are any changes.
I am new in android programming so I tried to write just a simple program that can call jni folder native cpp file method from java.. Though I have tried to run OPENCV example and tried the same way to call but none of the m worked out not even OpenCV Tutorial 2 - Mixed Processing. It launch and crash in my emulator.
com_rukna_myfirstandroidimageapp_MainActivity.h
extern "C"{
* Class: com_rukna_myfirstandroidimageapp_MainActivity
* Method: getStringfromNative
* Signature: (I)Ljava/lang/String;
JNIEXPORT jstring JNICALL Java_com_rukna_myfirstandroidimageapp_MainActivity_getStringfromNative
(JNIEnv *, jobject, jint);
}
CPPCALL.cpp
#include <com_rukna_myfirstandroidimageapp_MainActivity.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
JNIEXPORT jstring JNICALL Java_com_rukna_myfirstandroidimageapp_MainActivity_getStringfromNative (JNIEnv *env , jobject obj, jint src)
{
return (env)->NewStringUTF("HELLO from JNI CPPCALL !!");
}
using command prompt I also used this at MYProject/bin/classpath/ javap -s -p MainActivity
----I got many with this---
public native java.lang.String getStringfromNative(int);
descriptor: (I)Ljava/lang/String;
but when I call this method from my MainActivity like below
package com.rukna.myfirstandroidimageapp;
import library
public class MainActivity extends Activity {
/* some declarations and other functions */
int a = 0;int b = 1;
String s = getStringfromNative( a); /*---> error when call for the cpp method*/
_field.setText(s);
_field.setSelection(_field.getText().toString().length());
public native String getStringfromNative(int a);
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
}
else{
System.loadLibrary("MyLib");}
}
}
I got the following error while running application:
java.lang.UnsatisfiedLinkError: Native method not found: com.rukna.myfirstandroidimageapp.MainActivity.getStringfromNative:(I)Ljava/lang/String;
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#OPENCV_CAMERA_MODULES:=off
#OPENCV_INSTALL_MODULES:=on
#OPENCV_LIB_TYPE:=SHARED
#OPENCV_LIB_TYPE:=STATIC
# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=STATIC
include D:/OpenCV-2.4.11-android-sdk/sdk/native/jni/OpenCV.mk
#LOCAL_MODULE := CLAHE_test
LOCAL_MODULE := MyLib
LOCAL_SRC_FILES := CPPCALL.cpp
#LOCAL_SRC_FILES := CLAHE_test.cpp
#LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := x86
APP_PLATFORM := android-19
When I check in myproject.apk then I found under MyFirstAndroidImageApp.apk\lib\x86
libhydrogen.so
libimageutils.so
liblept.so
libMyLib.so
libnative_camera_r2.3.3.so
libnative_camera_r3.0.1.so
libnative_camera_r4.0.3.so
libnative_camera_r4.1.1.so
libnative_camera_r4.2.0.so
libnative_camera_r4.3.0.so
libnative_camera_r4.4.0.so
libopticalflow.so
libtess.so
Project Properties->C/C++ general-> Paths and Symbols-> Includes -> GNU C++
${NDKROOT}/platforms/android-9/arch-arm/usr/include
${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/include
${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include
${NDKROOT}/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/include
D:/OpenCV-2.4.11-android-sdk/sdk/native/jni/include
D:\android-ndk-r10d\platforms\android-19\arch-x86\usr\include
Help me as when I call same method without any argument then it runs normal I didn't get it why..... Do I need to give a constructor kind of thing if Yes then where and how?
Did you try to modify APP_ABI := armeabi-v7a in Application.mk. Also, if the cpp is successfully compiled, you should find so file in libs/armeabi-v7a
I'm working on a Android project which uses JNI. After 2 days of debugging, i still get an error: An unsatisfied link error:
Java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.samples.facedetect.Hello.sayHello:()V
There are many people who have had this problem before, so i have read and tried many possible solutions but i still can't get it to work :(
My code:
Hello.java =
public class Hello {
public static native void sayHello();
static {
Log.i("JNI", "Loading hello");
System.loadLibrary("hello");
}
}
Hello_jni.cpp =
#include <jni.h>
#include <Hello_jni.h>
#include <stdio.h>
#include <android/log.h>
#define LOG_TAG "FaceDetection/DetectionBasedTracker"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
extern "C" JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_Hello_sayHello
(JNIEnv *env, jclass obj)
{
printf("Hello world!\n");
LOGD("werkt");
return;
}
Hello_jni.h =
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_opencv_samples_facedetect_Hello */
#ifndef _Included_org_opencv_samples_facedetect_Hello
#define _Included_org_opencv_samples_facedetect_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_opencv_samples_facedetect_Hello
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_Hello_sayHello
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
Android.mk = (first part is for other module from openCV. I'm using the facedetection example from openCV as template for my application)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#OPENCV_CAMERA_MODULES:=off
#OPENCV_INSTALL_MODULES:=off
#OPENCV_LIB_TYPE:=SHARED
include ../../sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := detection_based_tracker
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILE := org_opencv_samples_facedetect_Hello_jni.cpp
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
from my main activity, i call Hello.sayHello() (static). This triggers the error.
Tried:
- Removing/adding 'Extern "C"' to sayHello() in the cpp file.
- Change function from native to not-native
The library seems to load fine, this is the whole error:
I/JNI(21440): Hello.sayHello() called
I/JNI(21440): Loading hello
D/dalvikvm(21440): Trying to load lib /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960
D/dalvikvm(21440): Added shared lib /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960
D/dalvikvm(21440): No JNI_OnLoad found in /data/data/org.opencv.samples.facedetect/lib/libhello.so 0x4248c960, skipping init
W/dalvikvm(21440): No implementation found for native Lorg/opencv/samples/facedetect/Hello;.sayHello:()V
D/AndroidRuntime(21440): Shutting down VM
W/dalvikvm(21440): threadid=1: thread exiting with uncaught exception (group=0x41a4e2a0)
E/AndroidRuntime(21440): FATAL EXCEPTION: main
E/AndroidRuntime(21440): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.samples.facedetect.Hello.sayHello:()V
E/AndroidRuntime(21440): at org.opencv.samples.facedetect.Hello.sayHello(Native Method)
If anybody can help me out, you would be a hero! I just can't get it to work...
Thanks in advance :)
Jelmer
Your dalvik runtime tells you exactly what is wrong:
W/dalvikvm(21440): No implementation found for native Lorg/opencv/samples/facedetect/Hello;.sayHello:()V
D/AndroidRuntime(21440): Shutting down VM
Which means that you haven't properly implemented your native method and java runtime can't find it. Such error occurs in runtime only, the lib compiles ok, which gives me a hunch, that either method name (in .h and .cpp file) is wrong and doesn't correspond to the jni naming format, or that there is an error in .cpp file.
It's working now, the problem was the Android.mk file. Thanks Vorren for giving the solution ;)
The working make file is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#OPENCV_CAMERA_MODULES:=off
#OPENCV_INSTALL_MODULES:=off
#OPENCV_LIB_TYPE:=SHARED
include ../../sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := detection_based_tracker
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := Hello_jni.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_LDLIBS += -llog
LOCAL_MODULE := hello
include $(BUILD_SHARED_LIBRARY)
there were two errors; syntax error LOCAL_SRC_FILE (missing the S), and i called 'my-dir' 2 times in the make file, which is prohibited (found this here: https://groups.google.com/forum/#!topic/android-ndk/Qmr_WQH-uKk)
I'm trying to create a cpp JNI file to allow me to do pretty much this tutorial in two calls so I can use this SURF Feature Detection in a Google Glass app. This error/problem that I'm having is not Google Glass related, but I believe Eclipse build environment related. I'm still relatively new to making projects in Eclipse, much less Android projects in Eclipse, so I'm pretty sure I'm missing something that's just ridiculously obvious and I need it pointed out to me. My main problem is that my final shared library file from the JNI is not being built, but the inbetween file is and my output from the build isn't indicating any explicit errors.
I know I should be able to build a JNI lib file that I can use in the Java in Android because JNI has been used in Android and I was also trying to follow the tutorials provided by the awesome person who made them here and here. These tutorials explain how to side-build the nonfree Opencv libs (the ones that contain SURF and SIFT) and put them in an Android project and how to utilize the libraries in JNI in the Android project.
My JNI code is the code from the very first link split into two functions, one that get called to setup the object keypoint setup that only needs to happen once and the other to get called on every frame in the Activity onCameraFrame() function.
#include <jni.h>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
using namespace std;
using namespace cv;
extern "C" {
// SURF Vars
Mat mat_object;
int minHessian = 500;
SurfFeatureDetector detector( minHessian );
vector<KeyPoint> kp_object;
SurfDescriptorExtractor extractor;
Mat des_object;
FlannBasedMatcher matcher;
vector<Point2f> obj_corners(4);
JNIEXPORT void JNICALL Java_com_example_android_glass_surfobjrec_Init_Surf(JNIEnv*,jobject, jlong addr_mat_object);
JNIEXPORT void JNICALL Java_com_example_android_glass_surfobjrec_Proc_Surf(JNIEnv*,jobject, jlong addr_mat_scene);
JNIEXPORT void JNICALL Java_com_example_android_glass_surfobjrec_Init_Surf(JNIEnv*,jobject, jlong addr_mat_object) {
Mat& mat_obj = *(Mat*) addr_mat_object;
mat_object = mat_obj;
//Detect the keypoints using SURF Detector
detector.detect( mat_object, kp_object );
// Calculate descriptors (feature vectors)
extractor.compute(mat_object, kp_object, des_object);
//Get the corners from the object
obj_corners[0] = cvPoint(0,0);
obj_corners[1] = cvPoint( mat_object.cols, 0 );
obj_corners[2] = cvPoint( mat_object.cols, mat_object.rows );
obj_corners[3] = cvPoint( 0, mat_object.rows );
}
JNIEXPORT void JNICALL Java_com_example_android_glass_surfobjrec_Proc_Surf(JNIEnv*,jobject, jlong addr_mat_scene) {
// Do all the stuff in the while loop in the oneDrive example
// EXCEPT, draw the keypoints using DrawKeypoints, don't use DrawMatches
Mat& mat_outputImg = *(Mat*) addr_mat_scene;
Mat mat_scene;
Mat des_scene;
vector<KeyPoint> kp_scene;
vector<vector<DMatch> > matches;
//vector<DMatch> matches;
vector<DMatch> good_matches;
vector<Point2f> obj;
vector<Point2f> scene;
vector<Point2f> scene_corners(4);
double max_dist = 0;
double min_dist = 100.0;
Mat H;
cvtColor(mat_outputImg, mat_scene, CV_BGR2GRAY);
// Detect and calculate keypoints on scene image
detector.detect(mat_scene, kp_scene);
extractor.compute(mat_scene, kp_scene, des_scene);
matcher.knnMatch(des_object, des_scene, matches, 2);
for(int k = 0; k < min(des_scene.rows-1,(int) matches.size()); k++) { //THIS LOOP IS SENSITIVE TO SEGFAULTS
if((matches[k][0].distance < 0.6*(matches[k][7].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0)) {
good_matches.push_back(matches[k][0]);
}
}
}
}
The only error that I am getting is matches[k][0].distance is saying "Field distance could not be resolved." I'm getting the same error with matches[k].size() and good_matches.push_back(matches[k][0]) says that matches is an invalid argument, but I've compiled all of this same code and run it fine from a regular CPP project in Eclipse using the code on the onedrive link. And these errors do not appear in the build messages.
And for the ndk-build I've pasted the Application.mk and Android.mk files below.
My Application.mk file is as below:
#APP_ABI := armeabi
APP_ABI += armeabi-v7a # you can do either armeabi or armeabi-v7a, steps are the same.
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-15
My Android.mk file is as below:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := nonfree_prebuilt
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_java_prebuilt
LOCAL_SRC_FILES := libopencv_java.so
include $(PREBUILT_SHARED_LIBRARY)
LOCAL_C_INCLUDES:= /Users/samanthahuston/Development/OpenCV-2.4.8-android-sdk/sdk/native/jni/include
LOCAL_MODULE := nonfree_jni
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS += -llog
LOCAL_SHARED_LIBRARIES := nonfree_prebuilt opencv_java_prebuilt
LOCAL_SRC_FILES := nonfree_jni.cpp
include $(BUILD_SHARED_LIBRARY)
Any help is greatly appreciated.
I'm testing the integrated static libraries in an Android app.
Unfortunately the compilation does not work! can you help me here?
I always get the error:
jni/main-jni.cpp: In function 'jint Java_com_tmz_cc_MainActivity_test1(JNIEnv*, jobject)': jni/main-jni.cpp:10:23: error: 'FileSync' has not been declared
make: *** [obj/local/armeabi/objs/ccSharedLib/main-jni.o] Error 1
I thought by the linker would be "FileSync" known.
Given the following:
project
+- ..
+-jni
+- include
+- prebuild
+- libFileSync.a
+- Android.mk
+- main-jni.cpp
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := fileSyncStaticLibrary
LOCAL_SRC_FILES := prebuild/libFileSync.a
LOCAL_EXPORT_C_INCLUDES := include/
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ccSharedLib
LOCAL_SRC_FILES := main-jni.cpp
LOCAL_STATIC_LIBRARIES := fileSyncStaticLibrary
include $(BUILD_SHARED_LIBRARY)
main-jni.cpp
#include <jni.h>
#include <stdio.h>
extern "C" {
jint Java_com_tmz_cc_MainActivity_test1( JNIEnv* env, jobject thiz) {
//FileSync *file = new FileSync("connection");
jstring seperator = FileSync::getPathSeperator();
jint temp = 0;
return temp;
}
jint Java_com_tmz_cc_MainActivity_test2( JNIEnv* env, jobject thiz) {
jint temp = 0;
return temp;
}
}
Error:
"Compile++ thumb : ccSharedLib <= main-jni.cpp
Reaping winning child 0x012d6098 PID 19632680
Cleaning up temp batch file C:\Users\jpenning\AppData\Local\Temp\make4148-1.bat
CreateProcess(C:\android\ndk\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-g++.exe,C:/android/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/ccSharedLib/main-jni.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Iinclude/ -IC:/android/ndk/sources/cxx-stl/system/include -Ijni -DANDROID -Wa,--noexecstack -IC:/android/ndk/platforms/android-14/arch-arm/usr/include -c jni/main-jni.cpp -o ./obj/local/armeabi/objs/ccSharedLib/main-jni.o,...)
Live child 0x12d6098 (obj/local/armeabi/objs/ccSharedLib/main-jni.o) PID 19632680
jni/main-jni.cpp: In function 'jint Java_com_tmz_cc_MainActivity_test1(JNIEnv*, jobject)':
jni/main-jni.cpp:10:23: error: 'FileSync' has not been declared
make: *** [obj/local/armeabi/objs/ccSharedLib/main-jni.o] Error 1
Reaping losing child 0x12d6098 PID 19632680
Removing child 0x12d6098 PID 19632680 from chain.
You must include the proper header file, e.g. #include <FileSync.h>, within main-jni.cpp.