12

朝!

JNIを介してJavaとC++の間でオブジェクトを動的にシリアル化できる小さなNDKプロジェクトを作成しました。ロジックは次のように機能します。

Bean-> JavaCInterface.Java-> JavaCInterface.cpp-> JavaCInterface.java-> Bean

問題は、この機能を他のプロジェクトで使用したいということです。プロジェクトからテストコードを分離し、「テスター」プロジェクトを作成しました。テスタープロジェクトは、JavaオブジェクトをC ++に送信し、C++はそれをJavaレイヤーにエコーバックします。

リンクは非常に簡単だと思いました-(NDK / JNIの「シンプル」は通常フラストレーションの日です)ソースプロジェクトとしてJNIBridgeプロジェクトを追加し、Android.mkに次の行を含めました。

NDK_MODULE_PATH=.../JNIBridge/jni/"

JNIBridge / jni / JavaCInterface / Android.mk:

...
include $(BUILD_STATIC_LIBRARY)

JNITester / jni / Android.mk:

...
include $(BUILD_SHARED_LIBRARY)
$(call import-module, JavaCInterface)

これはすべて正常に機能します。JavaCInterfaceモジュールのヘッダーに依存するC++ファイルは正常に機能します。また、JavaクラスはJNIBridgeプロジェクトのインターフェースをうまく使用できます。すべてのリンクは幸せです。

残念ながら、ネイティブメソッド呼び出しを含むJavaCInterface.javaは、静的ライブラリにあるJNIメソッドを認識できません。(論理的には同じプロジェクトにありますが、両方とも上記のメカニズムを介して使用するプロジェクトにインポートされます)。

私の現在の解決策は次のとおりです。私が達成しようとしていることのモジュール性を維持する何かを誰かが提案できることを願っています:


私の現在の解決策は、次のように呼び出し元のプロジェクトにJavaCInterfacecppファイルを含めることです。

LOCAL_SRC_FILES := FunctionTable.cpp $(PATH_TO_SHARED_PROJECT)/JavaCInterface.cpp

ただし、JavaCInterfaceアーキテクチャを変更した場合、依存する各プロジェクトを更新する必要が生じるため、これは行いません。


各ローカルプロジェクトに新しいJNIメソッドシグネチャのセットを作成し、インポートされたモジュールにリンクすることができます。繰り返しますが、これは実装を緊密にバインドします。

4

1 に答える 1

16

たくさんの血の汗と涙の後、私はこれを理解しました。

  • Android JNIは、そのバイナリをSHARED_LIBRARYのみからロードします。
  • JNIは、ロードされた共有ライブラリからの適切なメソッドシグネチャ/スタブにネイティブ呼び出しをリンクしようとします(リンクされた共有ライブラリの内部は検索されません)。
  • これらのメソッドを使用して静的ライブラリを作成し、アプリケーションで使用される共有ライブラリに組み込むことができます。

Andriod.xmlの次のコードを使用して、元のプロジェクトで静的ライブラリをビルドできます。

include $(CLEAR_VARS)
LOCAL_CFLAGS    := -O0
LOCAL_MODULE    := LibraryToBeUsedInsideSharedLib
LOCAL_SRC_FILES := ...
include $(BUILD_STATIC_LIBRARY) // This builds a "Static Object" here:
                                // /Project/obj/local/armeabi/libLibraryToBeUsedInsideSharedLib.a

include $(CLEAR_VARS)
LOCAL_MODULE       := LibraryCalledFromJava
LOCAL_SRC_FILES    := ...
LOCAL_STATIC_LIBRARIES := LibraryToBeUsedInsideSharedLib
include $(BUILD_SHARED_LIBRARY)

LOCAL_STATIC_LIBRARIES共有ライブラリに静的ライブラリが含まれます。Javaコードでは、これを呼び出すことができます。

System.loadLibrary("LibraryCalledFromJava");

LibraryToBeUsedInsideSharedLibJavaコードの任意の場所から、ライブラリ内にある任意のネイティブメソッドを呼び出すことができるはずです。

libLibraryToBeUsedInsideSharedLib.aこれを外部プロジェクトのAndroid.xmlに追加することで、ファイルをエクスポートして他のプロジェクトで使用できます。

include $(CLEAR_VARS)
LOCAL_MODULE            := LibraryToBeUsedInsideSharedLib
LOCAL_LDLIBS            := -llog/
LOCAL_SRC_FILES         := $(MY_PREBUILT_LIB_DIR)/libLibraryToBeUsedInsideSharedLib.a
include $(PREBUILT_STATIC_LIBRARY)
于 2011-06-16T09:41:29.347 に答える