2

私はこの例を実行して理解しようとしています:http://answers.oreilly.com/topic/2689-how-to-use-the-android-ndk-to-improve-performance/

これは、次のファイルを使用した非常に単純な例です。

FibActivity.java - main activity file
FibLib - class implementing and calling the native functions
fib.c - the C source file with the native functions and code
FibLib.h - the C header file, automatically created from the FibLib class
Android.mk - the makefile

説明どおりに例を実装しました。それでも、実行すると、アプリがネイティブコードにアクセスしようとすると、次の(UnsatisfiedLinkError)エラーが発生します。

12-21 11:31:53.042: D/dalvikvm(1491): Trying to load lib /data/data
/com.frank.android.ndk/lib/libfib.so 0x405143b8
12-21 11:31:53.042: D/dalvikvm(1491): Added shared lib /data/data/com.frank.android.ndk
/lib/libfib.so 0x405143b8
12-21 11:31:53.042: D/dalvikvm(1491): No JNI_OnLoad found in /data/data
/com.frank.android.ndk/lib/libfib.so 0x405143b8, skipping init
12-21 11:31:53.093: W/dalvikvm(1491): No implementation found for native Lcom/frank
/android/ndk/FibLib;.fibN (I)J
12-21 11:31:53.102: D/AndroidRuntime(1491): Shutting down VM
12-21 11:31:53.102: W/dalvikvm(1491): threadid=1: thread exiting with uncaught 
exception (group=0x40015560)
12-21 11:31:53.112: E/AndroidRuntime(1491): FATAL EXCEPTION: main
12-21 11:31:53.112: E/AndroidRuntime(1491): java.lang.UnsatisfiedLinkError: fibN
12-21 11:31:53.112: E/AndroidRuntime(1491): at 
com.frank.android.ndk.FibLib.fibN(Native Method)
12-21 11:31:53.112: E/AndroidRuntime(1491): at 
com.frank.android.ndk.JavaNativeFibonacciAct
ivity.onClick(JavaNativeFibonacciActivity.java:52)

logcatによると、私が気付いた唯一の奇妙なことは、eclipseが/ libフォルダーからライブラリーをロードしようとし、自動的に作成されたフォルダーは/libsと呼ばれることです。ただし、/libフォルダーの名前を/libsに変更し、すべてを再構築しても違いはありません。

誰かアイデアがありますか?javahを使用してヘッダーファイルを作成するなどの例を機能させるために、何日も努力してきました。メインアクティビティとcファイルのみを作成し、メインアクティビティからネイティブコードを呼び出すことは機能しているようですが、ヘッダーファイルの使用を開始するとすぐにUnsatisfiedLinkErrorが発生します。

アップデート:

FibLib.javaから:

// Native implementation
static {
    System.loadLibrary("fib"); // 
}

// Native implementation - recursive
public static native long fibN (int n);

// Native implementation - iterative
public static native long fibNI (int n);

fib.cファイル:

#include "com_frank_android_ndk_FibLib.h" /*  */

/* Recursive Fibonacci Algorithm  */
long fibN(long n) {
    if(n<=0) return 0;
    if(n==1) return 1;
    return fibN(n-1) + fibN(n-2);
}

/* Iterative Fibonacci Algorithm  */
long fibNI(long n) {
    long previous = -1;
    long result = 1;
    long i=0;
    int sum=0;
    for (i = 0; i <= n; i++) {
        sum = result + previous;
        previous = result;
        result = sum;
    }

    return result;
}

/* Signature of the JNI method as generated in header file  */
JNIEXPORT jlong JNICALL Java_com_frank_android__ndk_fibN (JNIEnv *env, jclass obj, jlong  n) {
    return fibN(n);
}

/* Signature of the JNI method as generated in header file  */
JNIEXPORT jlong JNICALL Java_com_frank_android__ndk_fibNI (JNIEnv *env, jclass obj, jlong  n) {
    return fibNI(n);
}

Andoid.mkファイル:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := fib
LOCAL_SRC_FILES := fib.c

include $(BUILD_SHARED_LIBRARY)
4

4 に答える 4

3

Javaパッケージ名は「com.frank.android.ndk」という名前で、Javaクラス名は「FibLib」という名前であるように見えます。したがって、FibNに一致するC関数の名前はJava_com_frank_android_ndk_FibLib_fibNである必要があります。このページはAndroidのドキュメントで参照されており、C関数のJNI命名規則について詳しく説明しています。

于 2012-12-23T03:13:35.643 に答える
1

見た目だけですか、それともC関数名が実際に単語ndkの前に二重アンダースコアを使用していますか?単一のアンダースコアIMHOである必要があります。

于 2012-12-21T18:27:30.067 に答える
1

見つかりませんLcom/frank/android/ndk/FibLib;.fibN。ログは、ライブラリが正常にロードされたことを示しています。

メソッドを呼び出す必要がありJava_com_frank_android_ndk_FibLib_fibNます; 質問では、二重アンダースコアがあり、クラス名がありません。同じことを解決する2つの異なるメソッドがある場合は、引数をエンコードすることによってそれらを区別することもできますが、ここでは必要ないようです。

これはCプログラムだとおっしゃっていましたが、CとC ++を混同することがあるので、これが「.cpp」ファイルの場合はextern "C"宣言に入れる必要があります。そうしないと、C++が関数を「マングル」します。名前。

http://developer.android.com/training/articles/perf-jni.html#faq_ULEも参照してください。

于 2012-12-21T23:07:56.610 に答える
0

ndk-buildを使用してJNiコードをコンパイルしましたか?クラス名は、JNIおよびJavaで説明されているものと同じである必要があります

Java_com_qualcomm_QCARSamples_VideoPlayback_VideoPlayback_initApplicationNative

initApplicationNativeはメソッド名であり、JavaとJNiの両方で同じである必要があります。そうでない場合は、このエラーが発生します。

于 2012-12-21T10:50:11.183 に答える