症状如下:
作为练习,为了在C代码中调用java的System.out.println()方法,我写了如下代码。
java代码片段如下:
[size=xx-small]
public class JNI_JAVA {
public static native void println(String str); // 在C代码里打算调用System.out.println()。
public static void main(String[] args) {
JNI_JAVA.println("Lady Gaga");
}
}
[/size]
生成如下头文件 JNI_JAVA.h 的片段:
[size=xx-small]
/*
[/size]
以下是我自己写的C代码 JNI_JAVA.C的片段:
[size=xx-small]
/*
Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_JNI_1JAVA_println
(JNIEnv *env, jclass clz, jstring str) {
//获取java.lang.system类
jclass cls_system = (**env).FindClass(env, "java/lang/System");
if (NULL == cls_system) {
fprintf(stderr, "Error %s:%d\n", FILE, LINE);
return;
}
//获取System.out的FID
jfieldID fid_out = (**env).GetStaticFieldID(env, cls_system, "out", "Ljava/io/PrintStream;");
if (NULL == fid_out) {
fprintf(stderr, "Error %s:%d\n", FILE, LINE);
return;
}
fprintf(stderr, "alive1\n");//正常输出
//获取System.out的对象
jobject obj_out = (**env).GetStaticObjectField(env, cls_system, fid_out);
if (NULL == obj_out) {
fprintf(stderr, "Error %s:%d\n", FILE, LINE);
return;
}
fprintf(stderr, "alive2\n");//正常输出
//[color=red]百分百死在下面这一句[/color]
//获取System.out.println()的MID
jmethodID mid_println = (**env).GetMethodID(env, obj_out, "println", "(Ljava/lang/String;)V");
fprintf(stderr, "alive3\n");//这句不会输出,下面也不会执行
if (NULL == mid_println) {
fprintf(stderr, "Error %s:%d\n", FILE, LINE);
return;
}
(**env).CallVoidMethod(env, obj_out, mid_println, str);
fprintf(stderr, "Yeah\n");
}
[/size]
执行到
jmethodID mid_println = (**env).GetMethodID(env, obj_out, "println", "(Ljava/lang/String;)V");
这一句时程序会死掉,同时给出以下输出:
//下面的alive1,alive2是我故意输出的
[size=xx-small]alive1
alive2
#
#
#
#
#
#
[/size]
[b]问题:
我调用 jmethodID mid_println = (**env).GetMethodID(env, obj_out, "println", "(Ljava/lang/String;)V"); 为啥会死??
是不是违反了什么安全限制,所以才使得程序死掉?[/b]
实话说,我真的没有看出你那句有什么问题。。。你先把
[quote]
jmethodID mid_println = (**env).GetMethodID(env, obj_out, "println", "(Ljava/lang/String;)V");
fprintf(stderr, "alive3\n");//这句不会输出,下面也不会执行
if (NULL == mid_println) {
fprintf(stderr, "Error %s:%d\n", FILE, LINE);
return;
}
(**env).CallVoidMethod(env, obj_out, mid_println, str);
[/quote]
你先把这2句话注释掉,看有没有问题
如果没问题换jdk再试试
我这里反正没问题的,给你看看
[code="java"]
jclass cls;
jfieldID fid;
jobject obj;
jmethodID mid;
cls = (*env)->FindClass(env, "java/lang/System");
if (cls == 0) {
printf("java/lang/System error\n");
return;
}
fid = (*env)->GetStaticFieldID(env, cls, "out", "Ljava/io/PrintStream;");
if (fid == 0) {
printf("java/lang/System::out error\n");
return;
}
obj = (*env)->GetStaticObjectField(env, cls, fid);
if (obj == 0) {
printf("GetStaticObjectField error\n");
return;
}
cls = (*env)->GetObjectClass(env, obj);
if (cls == 0) {
printf("GetObjectClass out error\n");
return;
}
mid = (*env)->GetMethodID(env, cls, "println", "(Ljava/lang/String;)V");
if (mid == 0) {
printf("println method error\n");
return;
}
(*env)->CallVoidMethod(env, obj, mid, s);
[/code]