【问题标题】:How to call Java functions from C++?如何从 C++ 调用 Java 函数?
【发布时间】:2010-10-23 14:27:21
【问题描述】:

如何从 C++ 应用程序调用 Java 函数?

我知道从 CMD(或类似技术)调用它们,但我宁愿不使用它们。

【问题讨论】:

    标签: java c++


    【解决方案1】:

    此页面很有帮助: http://hildstrom.com/projects/jni/index.html

    假设你有一个 Java 类:

    package foo;
    public class bar {
        public static int timesTen(int input){
            return input * 10;
        }
    }
    

    一旦你有了 JVM 和 JNIEnv*(细节省略...)你就可以从 C++ 调用 Java 方法,如下所示:

    jclass myClass = env->FindClass("foo.bar");
    jmethodID mid = env->GetStaticMethodID(myClass, "timesTen", "(I)I");
    jint hundred = env->CallStaticIntMethod(myClass, mid, (jint)10);
    

    这掩盖了很多细节,包括异常处理,如果省略这些细节会使你的 JVM 崩溃。有关“Java Native Interface”的所有详细信息,请搜索并点击 Oracle 链接。

    既然有人问...这是获得 Env* 的方法。请注意,如果 JVM 调用您的本机代码,则它已经有一个 Env*。

    JNIEnv* env(0);
    jint rv = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
    if (rv == JNI_OK) {
        return env;
    } else if (rv == JNI_EDETACHED) {
        // This happens if you created the thread, not the JVM
        rv = vm->AttachCurrentThread((void**)&env, 0);
        if (rv != JNI_OK) {
            // error
        }
    } else {
        // error
    }
    

    我怎么强调都不过分,使用 JNI 从 C/C++ 调用 Java 非常繁琐且容易出错。错误是神秘的和低级的。您必须处理异常,并且您必须分离线程,否则事情会变得很糟糕。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 你从哪里得到env
    • 那是“细节省略部分” ;-) 基本上,你创建一个JVM,那么每个线程必须有一个Env。我加了一点sn-p。你还必须在它们退出之前从 JVM 中分离本机线程,否则你会得到严重的错误。
    【解决方案2】:

    另一种从 CPP 调用 java 方法的简单方法是通过批处理文件。

    system() 
    

    是从 CPP 调用 exe 或 bat 文件的方法。将带有 java 路径和类路径的类放入批处理文件中,并使用 system("batch-file-name.bat") 从 CPP 调用该批处理文件。

    这很简单直接。

    【讨论】:

      【解决方案3】:

      查看JNI Invocation interface。这将允许您在 C(或 C++)应用程序中嵌入 JVM。

      请注意,存在各种更简单的机制来促进从 Java 调用 C/C++(例如JNA)。可能值得考虑反转您的问题,以便您可以从 Java 调用 (我知道这对于您的特定应用程序来说可能是不可能的)

      【讨论】:

      • 这不是你的错,但 JNI Infocation 接口链接已损坏。似乎 Oracle 移动了他们拥有的所有 JNI 资源,因为在查找 JNI 信息时,损坏的链接到处都是。
      • 链接好像已经修复了
      【解决方案4】:

      例如,检查Creating a JVM from C。它显示了创建 JVM 和调用方法的示例过程。如果JVM已经存在;例如你的 C 程序被 Java 程序调用(回调情况),你可以缓存 JNIEnv* 指针。

      作为建议,请小心从 C/C++ 缓存指向 JVM 的指针,其中涉及到一些关于您可以缓存哪些内容以及稍后可以调用它的语义。为此,正如 Brian Agnew 指出的那样,请查看 JNI 参考。

      【讨论】:

      • 我正在寻找这种类型的调用。问题是这种方法的缺点是什么
      • 复杂性。但我相信,没有第三方工具,这是我所读到的唯一方法。
      • RE:“如果 JVM 已经存在;例如,您的 C 程序被 Java 程序调用(回调情况),您可以缓存 JNIEnv* 指针。”每个线程都有自己的JNIEnv,线程之间不要共享。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      相关资源
      最近更新 更多