KimCherWoo 2010-12-09 20:50
浏览 353
已采纳

JNI 调用GetMethodID 获得System.out.println()方法的jmethodid时出错的问题。

症状如下:

作为练习,为了在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]
/*

  • Class: JNI_JAVA
  • Method: println
  • Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_JNI_1JAVA_println (JNIEnv *, jclass, jstring);

[/size]

以下是我自己写的C代码 JNI_JAVA.C的片段:
[size=xx-small]
/*

  • Class: JNI_JAVA
  • Method: println
  • 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
#

An unexpected error has been detected by HotSpot Virtual Machine:

#

SIGSEGV (0xb) at pc=0x00000000, pid=11192, tid=3076175552

#

Java VM: Java HotSpot(TM) Client VM (1.5.0_19-b02 mixed mode, sharing)

Problematic frame:

C 0x00000000

#

An error report file with more information is saved as hs_err_pid11192.log

#

If you would like to submit a bug report, please visit:

http://java.sun.com/webapps/bugreport/crash.jsp

#
[/size]

[b]问题:
我调用 jmethodID mid_println = (**env).GetMethodID(env, obj_out, "println", "(Ljava/lang/String;)V"); 为啥会死??
是不是违反了什么安全限制,所以才使得程序死掉?[/b]

  • 写回答

1条回答 默认 最新

  • beneo 2010-12-10 08:39
    关注

    实话说,我真的没有看出你那句有什么问题。。。你先把
    [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]

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 有偿,谁有移远的EC200S固件和最新的Qflsh工具。
  • ¥15 找一个QT页面+目标识别(行人检测)的开源项目
  • ¥15 有没有整苹果智能分拣线上图像数据
  • ¥20 有没有人会这个东西的
  • ¥15 cfx考虑调整“enforce system memory limit”参数的设置
  • ¥30 航迹分离,航迹增强,误差分析
  • ¥15 Chrome Manifest扩展引用Ajax-hook库拦截请求失败
  • ¥15 用Ros中的Topic通讯方式控制小乌龟的速度,走矩形;编写订阅器代码
  • ¥15 LLM accuracy检测
  • ¥15 pycharm添加远程解释器报错