29

独自の jni ソースを作成しようとしています。いくつかの ndk サンプルを見ると、マクロ JNIEXPORT と JNICALL の後に、このような Java パッケージの名前が続くことがよくあります。

JNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(JNIEnv * env, jobject obj, jobject bitmap, jlong time_ms)

私はそれをグーグルで検索しましたが、これらのマクロをいつどのように使用するのか理解できません

4

4 に答える 4

40

JNIEXPORT と JNICALL は NDK_ROOT/platforms/android-9/arch-arm/usr/include/jni.h で定義されています。セットアップに応じて、このパスは異なりますが、ほとんど同じです。

#define JNIIMPORT
#define JNIEXPORT  __attribute__ ((visibility ("default")))
#define JNICALL

JNIEXPORT は、ビルドされたバイナリ (*.so ファイル) の動的テーブルにネイティブ関数を表示するために使用されます。それらは「非表示」または「デフォルト」に設定できます (詳細はこちら)。これらの関数が動的テーブルにない場合、JNI はそれらを呼び出す関数を見つけることができないため、RegisterNatives 呼び出しは実行時に失敗します。

すべての関数はデフォルトで動的テーブルに配置されるため、誰でも簡単にネイティブ コードを逆コンパイルできることに注意してください。JNI がそれを見つける必要がある場合に備えて、すべての関数呼び出しはバイナリに組み込まれています。これは、コンパイラ オプションを使用して変更できます-fvisibility。コードを安全に保つためにこれを に設定し-fvisibility=hidden、JNIEXPORT を使用して関数に外部可視性があることを示すフラグを設定することをお勧めします。

strip コマンドを使用すると、デバッグ シンボルが削除されるだけで、動的テーブルは分離されます。objdump を試して、あなたの .so ファイルからどれだけの情報が得られるかを確認してください。

私たちは最近これにつまずきました。これが誰かの助けになることを願っています。

編集: カスタム ビルド システムを使用しているため、可視性オプションはデフォルトで他のビルド設定に設定されている場合があります。詳細については、この SO answerを参照してください。

于 2014-01-30T09:22:42.757 に答える
3

ネイティブ クラスで「javah」を実行し、生成されたものを使用するだけです。100% の信頼性でそれを生成できるツールがあれば、この詳細を知る必要はありません。

于 2013-10-17T09:31:59.750 に答える