【发布时间】:2011-09-26 17:46:57
【问题描述】:
我正在尝试从 C++ 调用 Java 函数。 到目前为止,这是我的代码:
#include <jni.h>
typedef struct JavaVMCreationResult {
JavaVM* jvm;
JNIEnv* env;
} JVMCreationResult;
JVMCreationResult* CreateJavaVM() {
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs args;
JavaVMOption opts[1];
opts[0].optionString = "-Djava.class.path=C:\\MyJavaClasses";
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
args.options = opts;
args.ignoreUnrecognized = JNI_TRUE;
JNI_GetDefaultJavaVMInitArgs(&args);
JNI_CreateJavaVM(&jvm, (void **) &env, &args);
JavaVMCreationResult* cres;
cres->jvm = jvm;
cres->env = env;
return cres;
}
int main() {
JVMCreationResult* cres = CreateJavaVM();
JavaVM* jvm = cres->jvm;
JNIEnv* env = cres->env;
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); // the evil line
}
我在 Windows 7 上使用带有 MinGW GCC 的 Code::Blocks。
main() 函数的最后一行使程序崩溃,但编译器没有抱怨任何事情。 (注释掉 jmethodID mid = env->GetSta... 行会使程序“不崩溃”)
我使用javap -s Main 来获得正确的方法签名,该类也是一个有效的Java 类。
你能告诉我程序崩溃的原因吗?这个例子只是在互联网上随处可见,但它对我不起作用。 :(
这是 Java 类:
public class Main {
public static void main(String[] args) {
System.out.println("This is from Java !");
}
}
解决方案
我没想到,当结构未初始化时,程序并没有早早崩溃,这对我来说似乎是不合逻辑的。但这确实是问题所在。
这是完整且有效的代码!
#include <jni.h>
#ifndef null
#define null NULL
#endif
typedef struct JavaVMCreationResult {
JavaVM* jvm;
JNIEnv* env;
} JVMCreationResult;
JVMCreationResult* CreateJavaVM() {
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs args;
JavaVMOption opts[1];
opts[0].optionString = "-Djava.class.path=C:\\Users\\Claudia\\Desktop";
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
args.options = opts;
args.ignoreUnrecognized = JNI_TRUE;
JNI_GetDefaultJavaVMInitArgs(&args);
JNI_CreateJavaVM(&jvm, (void **) &env, &args);
JVMCreationResult* cres = new JVMCreationResult();
cres->jvm = jvm;
cres->env = env;
return cres;
}
int main() {
JVMCreationResult* cres = CreateJavaVM();
JavaVM* jvm = cres->jvm;
JNIEnv* env = cres->env;
jclass cls = env->FindClass("Main");
if (cls) {
printf("Yes !\n");
}
else {
printf("No !\n");
}
jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(cls, mid);
printf("At end of Program.");
}
【问题讨论】:
-
您的变量“cres”是 CreateJavaVM 调用中从未初始化的点,因此您可能在该点取消引用空指针或其他无效指针。
-
这不是意味着程序应该在
JavaVM* jvm = cres->jvm;处崩溃吗?为什么它没有初始化? (我不是 C++ 专家,几周前就开始了。)谢谢 -
你怎么知道它在 main() 的最后一行崩溃了?
-
@Niklas 是的,
cres没有指向分配的内存。实际上,如果有什么问题,它应该会在cres->jvm = jvm上崩溃。 -
编译器无法检测空指针,因为它们是在运行时生成的。
标签: java c++ java-native-interface