JNI在我的项目中,但无法正常工作...
weather_myapp_com_opencvdemo_ImageUtils.h
#include <jni.h>
/* Header for class weather_myapp_com_opencvdemo_ImageUtils */
#ifndef _Included_weather_myapp_com_opencvdemo_ImageUtils
#define _Included_weather_myapp_com_opencvdemo_ImageUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: weather_myapp_com_opencvdemo_ImageUtils
* Method: test
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_weather_myapp_com_opencvdemo_ImageUtils_test
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
nativeapi.cpp
#include <jni.h>
#include "weather_myapp_com_opencvdemo_ImageUtils.h"
JNIEXPORT jstring JNICALL Java_weather_myapp_com_opencvdemo_ImageUtils_test
(JNIEnv *env, jobject obj){
return env->NewStringUTF("This just a test for Android Studio NDK JNI developer!");
}
日志
07-02 20:09:05.304 6306-6306/weather.myapp.com.opencvdemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: weather.myapp.com.opencvdemo, PID: 6306
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String weather.myapp.com.opencvdemo.ImageUtils.test() (tried Java_weather_myapp_com_opencvdemo_ImageUtils_test and Java_weather_myapp_com_opencvdemo_ImageUtils_test__)
at weather.myapp.com.opencvdemo.ImageUtils.test(Native Method)
at weather.myapp.com.opencvdemo.MainActivity.onCreate(MainActivity.java:15)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
但我将.cpp更改为.c,它的工作很有趣
nativeapi.c
#include <jni.h>
#include "weather_myapp_com_opencvdemo_ImageUtils.h"
JNIEXPORT jstring JNICALL Java_weather_myapp_com_opencvdemo_ImageUtils_test
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
}
.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "weather.myapp.com.opencvdemo"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "openCV"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// sourceSets.main {
// jni.srcDirs = []
// jniLibs.srcDir "src/main/libs"
// }
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
}
为什么将.c ++更改为.c会很有趣?以及如何解决此问题。
最佳答案
说明:
您的测试函数声明为:
extern“ C” JNIEXPORT jstring JNICALL Java_weather_myapp_com_opencvdemo_ImageUtils_test
(JNIEnv *,jclass);
函数定义为:
JNIEXPORT jstring JNICALL Java_weather_myapp_com_opencvdemo_ImageUtils_test
(JNIEnv * env,jobject obj){...}
具有不同的函数签名,因此函数声明不适用于您的测试函数,因此请使用extern关键字。结果,测试函数将受到C ++名称修改的约束。
解决方案(重访):
如果本机方法是静态的,则实现和声明都必须具有第二个“ jclass”类型的参数,否则,两者都必须具有“ jobject”第二个参数。