2016-07-02 2 views
0

JNI в моем проекте, но это не работает весело ...
weather_myapp_com_opencvdemo_ImageUtils.hандроид JNI C++ UnsatisfiedLinkError

#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

Объяснение:

ваш тест функция декларации:

ехЬегп "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 ключевое слово. Как следствие, функция test будет подвержена изменению имени языка C++.

Решение (повторно):

Если нативный метод является статическим, как реализация и декларация должна иметь второй аргумент типа «JClass», в противном случае, они оба должны иметь «jobject» второй аргумент ,

+0

Если объявление функции генерируется javah, оно, вероятно, является правильным, поэтому было бы лучше изменить определение, чтобы оно соответствовало декларации (а не наоборот). – user2543253

+0

@ user2543253 Документация jni диктует использование jobject. Однако, любой случай работает, поскольку jclass является подклассом jobject. – EHH

+0

для статических методов это 'jclass', и хотя он может« работать », он делает код менее понятным. – user2543253

Смежные вопросы