質問

朝!

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

bean-> javacinterface.java-> javacinterface.cpp-> javacinterface.java-> bean

問題は、他のプロジェクトでこの機能を使用したいことです。テストコードをプロジェクトから分離し、「テスター」プロジェクトを作成しました。テスタープロジェクトは、Javaオブジェクトを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メソッドを確認できません。 (論理的には同じプロジェクトにありますが、両方ともプロジェクトにインポートされ、上記のメカニズムを介してそれらを使用したいと考えています)。

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


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

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

しかし、Javacinterfaceアーキテクチャを変更した場合、プロジェクトに応じて各更新を必要とすることにつながるので、私はこれをしたくありません。


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

役に立ちましたか?

解決

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

  • Android JNIは、aからバイナリをロードします 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");

内部にあるネイティブメソッドを呼び出すことができるはずです LibraryToBeUsedInsideSharedLib Javaコードの任意の時点からライブラリ。

エクスポートできます 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)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top