gpt4 book ai didi

java - Android C/C++ native 调用 Java API

转载 作者:行者123 更新时间:2023-11-29 05:57:20 24 4
gpt4 key购买 nike

Android C/C++原生调用Java API的例子有很多。但是,我读过的所有这些示例都是 Android Java API 调用 native 首先,然后 native 使用传递的 JNI-ENV 调用其他 Java API。

没有传入的JNI-ENV,C/C++怎么获取呢?C/C++ native 是否可以在没有 JNI-ENV 的情况下调用 Java API?

如果可能的话,你能举个例子或链接吗?

谢谢!

最佳答案

您需要先包含jni.h。这会带来大量有用的调用;对于较新的 android 版本,您还需要 JniInvocation.h。要启用此功能:

LOCAL_C_INCLUDES += ${JNI_H_INCLUDE}

这当然适用于源代码树,不确定 NDK,但也应该没问题。

其次,非常重要的是选择合适的信号链库。 Art 或 Dalvik 将加载 libsigchain.so,这是一个 stub 和 abort() 每次调用其任何方法时。在 Android 上,它通过一个小 hack 完成:本地符号被导出到全局符号表,因此 Art 选择 exec 的符号而不是加载共享库。这是如何完成的:

# Enable native helper calls
LOCAL_SHARED_LIBRARIES += libnativehelper

# Include all of the Android's libsigchain symbols
LOCAL_WHOLE_STATIC_LIBRARIES += libsigchain

# Export only libsigchain symbols to global symbol table.
LOCAL_LDFLAGS += \
-Wl,--export-dynamic \
-Wl,--version-script,art/sigchainlib/version-script.txt

现在链接您的可执行文件。仔细检查是否确实导出了所需的符号:

% readelf -a <output_binary> | grep InitializeSignalChain
654: 0002cab1 211 FUNC GLOBAL PROTECTED 12 InitializeSignalChain

完成了吗?现在事情变得简单了:

  1. 初始化 JNI(以便您的代码使用正确的 VM)

    JniInvocation invocation;
    if (invocation.Init(nullptr)) return;
  2. 创建 JavaVM:

    JavaVM* vm;
    JNIEnv* env;
    JavaVMInitArgs* args;

    args.version = JNI_VERSION_1_4; // _5, _6
    args.options = nullptr;
    args.nOptions = 0;
    args.ignoreUnrecognized = JNI_FALSE;

    if (JNI_CreateJavaVM(&vm, &env, &args) < 0) return;
  3. 此时您的vmenv 已经可以使用了。玩得开心。

  4. 检查异常情况,如果有的话

    if (env->ExceptionCheck()) {
    // ...
    }
  5. 完成后,清理

    vm->DetachCurrentThread();
    vm->DestroyJavaVM();

可以找到更多有趣的东西hereDalvikVM Main可能是最好的知识来源。祝你好运!

关于java - Android C/C++ native 调用 Java API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11573406/

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