web-dev-qa-db-ja.com

Android NDK C ++ JNI(ネイティブの実装が見つかりません...)

C++でNDKを使用しようとしていますが、メソッドの命名規則を正しく取得できないようです。私のネイティブメソッドは次のとおりです:

extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
   //
}
}

extern "C" {} asloでラップされたヘッダー付き。

すべてが正常にコンパイルされ、.soファイルが作成され、プロジェクトの下のlibsフォルダーにコピーされますが、Eclipseでデバッグして実行すると、「ネイティブの実装が見つかりません...」というログcatメッセージが表示されます。すべてのNDKの例がCにあるため、私が見逃しているものはありますか?

ありがとう。

79
Patrick Kafka

「実装が見つかりません」につながる可能性のあるものがいくつかあります。 1つは関数プロトタイプ名を間違えていること、もう1つは.soをまったくロードできないことです。メソッドが使用される前にSystem.loadLibrary()が呼び出されていると確信していますか?

JNI_OnLoad関数が定義されていない場合は、作成して、libが正常に引き込まれたことを確認するためだけにログメッセージを吐き出すことができます。

extern "C"の使用を忘れている最も一般的な問題をすでに回避しているため、上記または若干のスペルミスのいずれかです。 Java宣言はどのように見えますか?

123
fadden

このエラーの追加の原因:装飾されていないネイティブメソッド名にアンダースコアを含めることはできません!

たとえば、AudioCapture_Ping()という名前のC関数をエクスポートしたいと考えました。 Cでのエクスポート宣言は次のとおりです。

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object);  //Notice the underscore before Ping

ここに私のJavaクラスが関数をインポートしています:

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapture_Ping();  // FAILS
    ...

アンダースコアを削除するまで、ネイティブメソッドに動的にリンクするためにAndroidを取得できませんでした:

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object); 

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapturePing();  // THIS WORKS!
    ...
18
user1222021

私も同じ問題を抱えていましたが、エラーはAndroid.mkファイルにありました。私はそれを持っていました:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp 

しかし、これが必要です:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp 

詳細に注意してください+ =代わりに:=

それがお役に立てば幸いです。

13
ademar111190

自動生成されたStudioの例で提供されているextern "C"を呼び出しましたが、次の関数を含む残りのファイル全体を{}括弧で囲むのを忘れていました。最初の機能のみが機能しました。

6
DragonLord
4
Megha

その他の理由:Android.mkでLOCAL_STATIC_LIBRARIESの代わりにLOCAL_WHOLE_STATIC_LIBRARIESを使用します。 NDKはJavaコードからのネイティブバインディングの使用を検出できないため、ライブラリが未使用のAPI呼び出しを最適化することを停止します。

4
John Twigg

Javah(Java SDK)の一部)を使用します。これにぴったりのツールです(.classファイルから.hヘッダーを生成します)。

2
MartinH

パッケージ名に_文字が含まれる場合、以下に示すように、_文字の後に1(one))と記述する必要があります。

MainActivity.Java

package com.example.testcpp_2;

native-lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
1
oiyio

私は同じ問題に直面しましたが、私の場合は、パッケージ名「RFID_Test」にアンダースコアが含まれていたため、パッケージの名前を変更して動作しました。ありがとうuser1222021

0
F.sh

上記のすべてのソリューションを試してみましたが、ビルドエラー(jni Java.lang.UnsatisfiedLinkError:No implementation found for ...)を解決できませんでした。最後に、verify.cppソースファイルをCMakeList.txtに追加するのを忘れていることがわかりましたadd_library segement(verify.cppはCtrl + Enterショートキー、または他のファイル名で自動生成されます)、私の応答がいずれかを助けることを願っています。

私のビルド環境:Gradle + CMake

0
user2420449