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


86

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

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

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

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

ありがとう。


を使用してJNIスタブを生成していますjavahか?そうでない場合は、そうする必要があります。:-P
クリスジェスター-ヤング

7
おそらくあなたが電話をしなかったからですSystem.loadLibrary
IgorGanapolsky 2016年

1
ご質問ありがとうございます。今日は新しいことを学びました。
Shady MohamedSherif19年

回答:


148

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

JNI_OnLoad関数が定義されていない場合は、関数を作成してログメッセージを吐き出し、libが正常にプルインされていることを確認することをお勧めします。

あなたはすでに最も一般的な問題(使用するのを忘れている)を避けたextern "C"ので、それは上記か、わずかなスペルミスのどちらかです。Java宣言はどのように見えますか?


13
イエス!...この私はちょうど私が私のLoadLibraryの呼び出しがコメントアウトしていた覚えていた読めば-あなたは私の仕事の時間の価値を保存
zeboidlund

11
あなたも私を救った!関数名と他のいくつかのことを4回チェックしました...しかし、extern "C"を忘れてしまい、質問でも気づきませんでした。
qwertie 2012年

1
現在Androidドキュメントサイトにあります:developer.android.com/training/articles/perf-jni.html#faq_ULE
fadden

2
誰も知らなかったケースも1つあります。アンダースコアはパッケージの区切り文字として解釈されるため、関数名に「_」(アンダースコア)を使用することはできません。したがって、キャメルケースの関数名のみが可能です
Nulik 2018

2
@Nulik:「_ 1」としてエスケープすると「_」を使用できます。
fadden 2018

18

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

たとえば、という名前のC関数をエクスポートしたいと思いAudioCapture_Ping()ます。これが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!
    ...

5
Java言語宣言での「_」の出現は、ネイティブ宣言で「_1」に置き換える必要があります。docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/…の表2-1を参照してください。
fadden 2017

1
非常に明白ですが、数時間のデバッグの後、私は自分でそれを理解することができませんでした...ありがとう、あなたは私を救いました!
George Atsev 2017

@ user1222021質問があります。プロジェクト内のすべてのアクティビティのcppメソッドをエクスポートできますか?.cppファイルのメソッドでアクティビティ名を指定する必要がありますか?
Balflear

14

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

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

しかし、これを持っている必要があります:

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

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

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


2
または、それらすべてを1行に追加するか、 `\`改行文字を使用することもできます。
IgorGanapolsky 2016年

6

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


4

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


1
違いはどこにありますか:「android.mkでLOCAL_STATIC_LIBRARIESの代わりにLOCAL_WHOLE_STATIC_LIBRARIESを使用する」
Josh

4

2
あなたは、Android NDKディストリビューションの一部であるアンドロイド- NDK /サンプル/ハロー-GL2中のcppファイルを見つけることができます
Yenchi


1
@pevikまた死んだ。
Mygod 2016年


リンクが再び
切れ

2

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


2

パッケージ名に_文字が含まれている場合は、以下に示すように、_文字の後に1(1)を書き込む必要があります。

MainActivity.java

package com.example.testcpp_2;

native-lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(

0

上記のすべての解決策を試しましたが、ビルドエラー(jni java.lang.UnsatisfiedLinkError:の実装が見つかりません...)を解決できませんでした。ついに、verify.cppソースファイルをCMakeList.txtに追加するのを忘れていることがわかりました。 add_library segement(verify.cppはCtrl + Enterショートキー、おそらく他のファイル名によって自動生成されます)、私の応答が誰かを助けることを願っています。

私のビルド環境:Gradle + CMake


0

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


-3

私は同じ問題に2回直面しました。たまたま、Android Studioからアプリを起動しようとした電話で、AndroidStudioにまだダウンロードしていないAPIレベルが使用されていました。

  1. AndroidStudioを最新バージョンにアップグレードします
  2. AndroidStudio内から必要なAPIをダウンロードします
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.