使用 Eclipse 从 Android 中的 C 代码调用 Java 函数而不调用 Java

Posted

技术标签:

【中文标题】使用 Eclipse 从 Android 中的 C 代码调用 Java 函数而不调用 Java【英文标题】:Call a Java function from C code in Android using Eclipse without calling Java 【发布时间】:2018-07-20 07:46:56 【问题描述】:

我想在没有共享库的情况下从 C 代码调用 Java 函数 并且之前没有调用一些 Java 函数。

我知道如何调用我的 Java 函数,但我需要获取 Env 和 JavaVM,但我真的不知道如何获取它。我不能使用JNI_CreateJavaVMJNI_OnLoad,因为我在android 上工作。我正在使用 android-ndk-r13b 构建 C 代码。

我正在使用 Eclipse Juno。

我该如何解决这个问题?

【问题讨论】:

没有 Java VM 就无法运行 Java 字节码。如果您不能或不想启动 JVM 或以某种方式向在您的进程之外运行的 JVM 提交请求,那么您就不走运了。 嘿!我强烈建议您尝试并详细说明您要做什么,因为我认为这不是很清楚。你有点指定你想做某事,即从 C 代码调用 Java 函数,然后说你想这样做而不做第二个,即不调用 Java 函数。我认为如果您尝试更好地解释它以确定它是否可能,这将对人们有很大帮助。 我需要修改运行用 C 代码编写的服务器的 droidVNCserver,因为我必须从该服务器调用一些 java 函数。没有选项可以在 C 中编写该 java 函数。 听起来在 C 中重写想要的函数可能正是你需要做的。您声称这不是一种选择的依据是什么? 我几乎不会重写android java函数。我需要使用android媒体库中的一些功能。 【参考方案1】:

根据我对 NDK 的使用,您可以从 android 调用 JNI_OnLoad 函数。从那里您可以使用静态方法或通过实例对象调用您想要的任何类。

jint JNI_OnLoad(JavaVM* vm, void* reserved)

    JNIEnv* env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) 
        return -1;
    
    return JNI_VERSION_1_6;

【讨论】:

如果我在我的 C 代码中使用它,我会得到错误:成员引用基类型“JavaVM”(又名“const struct JNIInvokeInterface ”)不是结构或联合。如果我将 vm-> 更改为 (*vm)-> ,我将收到错误:函数调用的参数太少,预期为 3,有 2 个。所以我尝试将其更改为 if ((*vm)->GetEnv(vm, (void**)(&env), JNI_VERSION_1_6) != JNI_OK)...全部吗?不需要一些“外部”什么的? 我认为现在问题出在 android make 文件中,因为库 androidvncserver 未加载。 我的错误是我使用的代码在 C++ 文件中,在这种情况下,您需要在代码上加上括号。您收到 JavaVM 错误的原因是因为 C 和 C++ 代码上的 JNIEnv 运行方式不同。在 C++ 中你不需要将 JNIEnv 传递给函数,而在 C 中你需要传递它,这就是为什么 C 要求 3 个参数而 C++ 要求 2 个参数的原因。所以你添加的解决方案应该可以正常工作。跨度> 我必须编译 shared_library 然后我从 Java 调用函数以将 Env 传递给 C 中的另一个函数以调用 Java 方法。 JNI 不适用于可执行的 C 代码...致 Adnrian:如果我从被调用函数所在的 Activity 加载库,此代码将起作用。 这个代码在static System.loadLibrary("library");被调用时被调用。这是我的 jni.cpp 文件中 JNI_OnLoad 函数的完整示例,extern "C JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) JNIEnv *env; if ((*vm).GetEnv((void **) &amp;env, JNI_VERSION_1_6) != JNI_OK) return JNI_ERR; return JNI_VERSION_1_6; "【参考方案2】:

在我看来,最好的方法是在您的 Java 代码中使用 RESTful API,这样您的 C 代码就可以通过 JSON 请求/响应访问该函数。如果您解释为什么需要 C 中的代码会很有帮助。C 代码是在一个单独的项目中还是由您的 Java 代码生成的?

【讨论】:

以上是关于使用 Eclipse 从 Android 中的 C 代码调用 Java 函数而不调用 Java的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Eclipse 中的 android 项目导入 Android Studio?

从android eclipse中的片段刷新或更新listadapter

在Eclipse中,如何从使用它的项目源中快速访问“android库项目”的源?

Eclipse 中的 Android 项目缺少“添加本机支持”

将应用程序从 Eclipse 移植到 Android Studio 时出错

无法从 SQLite 检索数据说 android (Eclipse) 中不存在该列