Question

Matin!

J'ai créé un petit projet de NDK qui permet sérialisation d'objets dynamiques entre Java et C ++ par JNI. La logique fonctionne comme ceci:

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

Le problème est que je veux utiliser cette fonctionnalité dans d'autres projets. Je choisis le code de test du projet et créé un projet « Tester ». Le projet testeur envoie un objet Java à travers C ++ qui est alors l'écho de retour à la couche Java.

Je pensais que Linking serait assez simple - ( « simple » en termes de NDK / JNI est généralement une journée de frustration) J'ai ajouté le projet JNIBridge comme projet source et y compris les lignes suivantes 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)

Cela fonctionne tout va bien. Le C les fichiers qui reposent sur les en-têtes de modules JavaCInterface excellent travail. De plus, les classes Java peuvent utiliser des interfaces heureusement de projet JNIBridge. Tout l'enchaînement est heureux.

Malheureusement JavaCInterface.java qui contient les appels de méthode native ne peut pas voir la méthode JNI situé dans la bibliothèque statique. (Logiquement, ils sont dans le même projet, mais les deux sont importés dans le projet où vous souhaitez les utiliser à travers le mécanisme ci-dessus).

Mes solutions actuelles sont sont ci-après. J'espère que quelqu'un peut suggérer quelque chose qui permettra de préserver la nature modulaire de ce que je suis en train de réaliser:


Ma solution actuelle serait d'inclure les fichiers cpp JavaCInterface dans le projet appelant comme ceci:

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

Mais je préfère ne pas le faire car il conduirait à me mettre à jour chaque besoin projet selon que je l'ai changé l'architecture JavaCInterface.


Je pourrais créer une nouvelle série de signatures de méthode JNI dans chaque projet local qui relient ensuite aux modules importés. Encore une fois, cette lie les mises en œuvre trop serré.

Était-ce utile?

La solution

Après beaucoup de sueur et de larmes de sang que j'ai compris cela.

  • Android JNI charge son binaire à partir d'une seule SHARED_LIBRARY.
  • JNI va essayer de relier les appels natifs aux signatures de méthode appropriée / talons de la bibliothèque partagée chargé (il ne sera pas regarder à l'intérieur des bibliothèques partagées liées).
  • Vous pouvez créer une bibliothèque statique avec ces méthodes et de construire dans la bibliothèque partagée utilisée par votre application.

Vous pouvez construire votre bibliothèque statique dans votre projet d'origine en utilisant le code suivant dans votre 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 inclut la bibliothèque statique dans votre bibliothèque partagée. Dans votre code Java, vous pouvez maintenant appeler ceci:

System.loadLibrary("LibraryCalledFromJava");

Vous devriez être en mesure d'appeler des méthodes natives situées à l'intérieur de la bibliothèque LibraryToBeUsedInsideSharedLib de tout point dans votre code java.

Vous pouvez exporter le fichier libLibraryToBeUsedInsideSharedLib.a et de l'utiliser dans d'autres projets en ajoutant à ce Android.xml du projet externe:

include $(CLEAR_VARS)
LOCAL_MODULE            := LibraryToBeUsedInsideSharedLib
LOCAL_LDLIBS            := -llog/
LOCAL_SRC_FILES         := $(MY_PREBUILT_LIB_DIR)/libLibraryToBeUsedInsideSharedLib.a
include $(PREBUILT_STATIC_LIBRARY)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top