【发布时间】:2010-10-23 14:27:21
【问题描述】:
如何从 C++ 应用程序调用 Java 函数?
我知道从 CMD(或类似技术)调用它们,但我宁愿不使用它们。
【问题讨论】:
如何从 C++ 应用程序调用 Java 函数?
我知道从 CMD(或类似技术)调用它们,但我宁愿不使用它们。
【问题讨论】:
此页面很有帮助: 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?
另一种从 CPP 调用 java 方法的简单方法是通过批处理文件。
system()
是从 CPP 调用 exe 或 bat 文件的方法。将带有 java 路径和类路径的类放入批处理文件中,并使用 system("batch-file-name.bat") 从 CPP 调用该批处理文件。
这很简单直接。
【讨论】:
查看JNI Invocation interface。这将允许您在 C(或 C++)应用程序中嵌入 JVM。
请注意,存在各种更简单的机制来促进从 Java 调用 C/C++(例如JNA)。可能值得考虑反转您的问题,以便您可以从 Java 调用 (我知道这对于您的特定应用程序来说可能是不可能的)
【讨论】:
例如,检查Creating a JVM from C。它显示了创建 JVM 和调用方法的示例过程。如果JVM已经存在;例如你的 C 程序被 Java 程序调用(回调情况),你可以缓存 JNIEnv* 指针。
作为建议,请小心从 C/C++ 缓存指向 JVM 的指针,其中涉及到一些关于您可以缓存哪些内容以及稍后可以调用它的语义。为此,正如 Brian Agnew 指出的那样,请查看 JNI 参考。
【讨论】: