【问题标题】:android jni c++ UnsatisfiedLinkErrorandroid jni c++ UnsatisfiedLinkError
【发布时间】:2016-07-02 14:44:59
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    解释:

    您的 test 函数声明是:

    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) {...}

    具有不同的函数签名,因此函数声明不适用于您的 test 函数,因此使用 extern 关键字。因此,test 函数将受到 C++ 名称修改的影响。

    解决方案(重新访问):

    如果本地方法是静态的,则实现和声明都必须有第二个类型为“jclass”的参数,否则,都必须有一个“jobject”第二个参数。

    【讨论】:

    • 如果函数声明是由 javah 生成的,它可能是正确的,所以最好更改定义以匹配声明(而不是相反)
    • @user2543253 jni 文档规定使用 jobject。但是,任何一种情况都有效,因为 jclass 是 jobject 的子类。
    • 对于静态方法,它是jclass,虽然它可能“工作”,但它使代码不太清晰。
    • 我不知道!你能提供一个链接吗??他的“测试”功能并不是一成不变的。
    • docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/…你怎么知道OP的方法不是静态的?
    猜你喜欢
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多