C + JNI:CallStaticCharMethod导致错误

时间:2017-01-06 08:58:04

标签: java c java-native-interface

我正在尝试将Java和C程序与JNI结合起来。我的目标是将一个String从JNI传递给C.我在调用CallStaticCharMethod时遇到错误(分段错误?)。我觉得我真的错过了如何做到这一点。我错过了什么?

我修改的示例来自here

helloWorld.java

public class helloWorld{
    public static void main(String[] args){
    System.out.println("Hello, World");
}
public static char hello(){
        String s = "H";
        char c = s.charAt( 0 );
        return c;
    }
}

hello_world.c

JNIEnv *create_vm(JavaVM **jvm) {
    JNIEnv *env;
    JavaVMInitArgs args;
    JavaVMOption options;
    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    options.optionString = "-Djava.class.path=./";
    args.options = &options;
    args.ignoreUnrecognized = 0;
    int rv;
    rv = JNI_CreateJavaVM(jvm, (void **) &env, &args);
    if (rv < 0 || !env)
        printf("Unable to Launch JVM %d\n", rv);
    else
        printf("Launched JVM! :)\n");
    return env;
}

void invoke_class(JNIEnv *env) {
    jclass hello_world_class;
    jmethodID main_method;
    jmethodID hello_method;
    jint number = 20;
    jint exponent = 3;   
    hello_method = (*env)->GetStaticMethodID(env, hello_world_class, "hello", "()C");

    //This line causes the error:
    (*env)->CallStaticCharMethod(env, hello_world_class, hello_method);
}
int main(int argc, char **argv) {
    JavaVM *jvm;
    JNIEnv *env;
    env = create_vm(&jvm);
    if (env == NULL)
        return 1;
    invoke_class(env);
    return 0;
    }

修改1

这是在错误日志中:

# Problematic frame:
# V  [libjvm.so+0x6f112a]  
JNI_ArgumentPusherVaArg::JNI_ArgumentPusherVaArg(_jmethodID*, _va_list_tag*)+0xa

1 个答案:

答案 0 :(得分:1)

您需要初始化hello_world_class作为上述提议的评论者。注意hello_world_class不是helloWorld类的实例。它是对类的引用 - 表示对类型的引用。您的C代码只知道方法名称,但它不知道类名。方法hello可以在很多类中定义,C代码必须知道它是什么类:

hello_world_class = (*env)->FindClass(env, "helloWorld");
hello_method = (*env)->GetStaticMethodID(env, hello_world_class, "hello", "()C");

在这种情况下没有必要有全局参考。简单FindClass就足够了。