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.
Related
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
My native method cannot be found and I cannot solve it.
java code:
package org.cocos2dx.cppemptytest;
public class TestJNI {
static {
System.loadLibrary("cpp_empty_test");
}
public native String moveto();
}
native code:
#include "AppDelegate.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include <stdlib.h>
#include "cocos2d.h"
#define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
AppDelegate *pAppDelegate;
void cocos_android_app_init (JNIEnv* env, jobject thiz) {
LOGD("cocos_android_app_init");
pAppDelegate = new AppDelegate();
}
extern "C" {
JNIEXPORT jstring JNICALL Java_org_cocos2dx_cppemptytest_TestJNI_moveto
( JNIEnv* env, jobject thiz){
return env->NewStringUTF("default");
}
}
in Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cpp_empty_test
LOCAL_MODULE_FILENAME := libcpp_empty_test
LOCAL_SRC_FILES := main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp
LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
$(LOCAL_PATH)/../../../../extensions \
$(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../../../../cocos/editor-support
LOCAL_STATIC_LIBRARIES := cocos2dx_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,.)
Output gives unsatisfied link error, but my naming is correct I guess. Are there any other reasons why this error occurrs?
E/AndroidRuntime(30310): java.lang.UnsatisfiedLinkError:
Native method not found:
org.cocos2dx.cppemptytest.TestJNI.moveto:()Ljava/lang/String;
Try to change your in Android.mk to this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcpp_empty_test
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
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)
This is the .cpp file and the code is
JNIEXPORT jint JNICALL Java_com_example_compute_MainActivity_AddNumbers(JNIEnv *env, jobject obj, jint v1, jint v2)
{
_android_log_print(ANDROID_LOG_VERBOSE, "VaxVoIP", "The value of 1 + 1 is %d", 1+1);
return -1;
//return (v1 + v2);
}
This is the Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
Here we give our module name and source file(s)
LOCAL_MODULE := add
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := add.cpp\
add.h\
include $(BUILD_SHARED_LIBRARY)
And the other error that I'm trying to solve is while making the .so file
_android_log_print(ANDROID_LOG_VERBOSE, "VaxVoIP", "The value of 1 + 1 is %d", 1+1);
was not declared in this scope
John is right about it. I just got it resolved by including #include <android/log.h>and also add LOCAL_LDLIBS += -llog -ldl -landroid in android.mk file
If that's the whole .cpp file, you're going to need to #include something that defines _android_log_print.
Don't forget to include
#include <android/log.h>
It's probably because of the buffer. Put \n at the end of the string.
__android_log_print(ANDROID_LOG_VERBOSE, "VaxVoIP", "The value of 1 + 1 is %d\n", 1+1);
Also don't forget to put double underscores rather than one single underscore.
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.