JNI“env-> GetStaticMethodID()"崩溃的程序 [英] JNI "env->GetStaticMethodID()" crashed program
问题描述
我正在尝试从C ++调用Java函数。
这是我到目前为止的代码:
I'm trying to call a Java function from C++. This is my code so far:
#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
}
我正在使用Code :: Blocks with MinGW GCC在Windows 7上。
main()函数的最后一行使程序崩溃,但编译器不会抱怨任何内容。 (注释 jmethodID mid = env-> GetSta ...
行使程序不崩溃)
我使用 javap -s Main
获取正确的方法签名,该类也是一个有效的Java类。
I'm using Code::Blocks with MinGW GCC on Windows 7.
The last line in the main() function crashes the Program, but the compiler does not complain about anything. (Commenting out the jmethodID mid = env->GetSta...
line makes the program "not crashing")
I have uses javap -s Main
to obtain the right method signature, also the class is a valid Java class.
你能告诉我为什么程序崩溃了吗?这个例子只是在互联网上随处可见,但它对我不起作用。 :(
Can you tell me why the Program crashes ? This example is just shown everywhere on the Internet but it doesn't work for me. :(
这是Java类:
public class Main {
public static void main(String[] args) {
System.out.println("This is from Java !");
}
}
解决方案
我不会想到它,似乎对于我来说,没有初始化结构时程序没有崩溃。但这确实是问题。
这是完整且正常工作的代码!
SOLUTION
I wouldn't have thought it, it seems unlogic to me that the program wasn't crashing earlier when the struct wasn't initialized. But this was really the issue.
This is the full and working code !
#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调用中从未初始化的一个点,因此您可能在该点取消引用null或其他无效指针。
Your variable "cres" is a point in the CreateJavaVM call that is never initialized, so you're probably dereferencing a null or otherwise invalid pointer at that point.
一种解决方案是定义cres(不是在main中指向cres的指针,并将指向的指针传递给CreateJavaVM作为参数,然后使用CreateJavaVM中的参数返回结果。
One solution is to define cres (not a pointer to cres) in main, and pass a pointer to that to CreateJavaVM as a parameter, and then use the parameter inside CreateJavaVM to return the result.
在JNI_CreateJavaVM调用之后检查jvm和env是否获得非空值是个好主意,并且在分别调用FindClass和GetStaticMethodID后cls和mid同样是非空的
Also it's a good idea to check that jvm and env get non-null values after the JNI_CreateJavaVM call, and that cls and mid are likewise non-null after the calls to FindClass and GetStaticMethodID, respectively
这篇关于JNI“env-> GetStaticMethodID()"崩溃的程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!