gpt4 book ai didi

java-native-interface - Android NDK 导入模块/代码复用

转载 作者:行者123 更新时间:2023-12-03 13:44:51 25 4
gpt4 key购买 nike

早晨!

我创建了一个小型 NDK 项目,它允许通过 JNI 在 Java 和 C++ 之间动态序列化对象。逻辑是这样工作的:

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

问题是我想在其他项目中使用这个功能。我从项目中分离出测试代码并创建了一个“Tester”项目。测试器项目将一个 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 项目中的接口(interface)。所有的链接都是快乐的。

不幸的是,包含 native 方法调用的 JavaCInterface.java 无法看到位于静态库中的 JNI 方法。 (从逻辑上讲,它们在同一个项目中,但都通过上述机制导入到您希望使用它们的项目中)。

我目前的解决方案如下。我希望有人可以提出一些可以保留我想要实现的模块化性质的东西:

我当前的解决方案是在调用项目中包含 JavaCInterface cpp 文件,如下所示:
LOCAL_SRC_FILES := FunctionTable.cpp $(PATH_TO_SHARED_PROJECT)/JavaCInterface.cpp

但我宁愿不这样做,因为如果我更改 JavaCInterface 架构,它会导致我需要更新每个依赖项目。

我可以在每个本地项目中创建一组新的 JNI 方法签名,然后链接到导入的模块。同样,这将实现绑定(bind)得太紧。

最佳答案

经过大量的汗水和泪水,我明白了这一点。

  • Android JNI 从 SHARED_LIBRARY 加载其二进制文件只要。
  • JNI 将尝试将本地调用链接到加载的共享库中的适当方法签名/ stub (它不会查看链接的共享库内部)。
  • 您可以使用这些方法创建静态库并将其构建到应用程序使用的共享库中。

  • 您可以使用 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)

    关于java-native-interface - Android NDK 导入模块/代码复用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6355055/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com