android jni c ++ UnsatisfiedLinkError

时间:2016-07-02 14:44:59

标签: java android c++ c java-native-interface

JNI在我的项目中,但它没有效果...... 的 weather_myapp_com_opencvdemo_ImageUtils.h

#include &ltjni.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 &ltjni.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 &ltjni.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它很有趣?以及如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

<强> 说明:

你的测试函数声明是:

  

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'第二个参数。