我正在尝试将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
答案 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
就足够了。