ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
你的原生代码必须使用合适的JNI函数把jstring对象转换为C/C++字符串。JNI支持Unicode和UTF-8字符串之间的双向转换。Unicode字符串使用16个字节标识字符,而UTF-8字符串则使用一种与7位ASCII码向上兼容的加密模式。UTF-8字符串就像以NULL结尾的C字符串,即使它包含了非ASCII字符。所有值在1到127的7位ASCII字符在UTF-8中保持着同样的加密方式。一个最高位为1的字节标识着一个多字节加密的16位Unicode字符的开始。 Java_Prompt_getLine函数调用JNI函数GetStringUTFChars来读取这个字符串中的内容。GetStringUTFChar函数可以通过JNIEnv接口指针调用,它将一个代表着Java虚拟机中的Unicode字符串的jstring引用,转换成为一个UTF-8形式的C字符串。如果你可以确定原始字符串仅仅包含七位的ASCII字符,那么你可以直接把转换之后的字符串传递给C库函数,比如printf.(我们将会在8.2节讨论如何处理非ASCII字符串)。 ~~~ #include <jni.h> #ifdef __cplusplus extern "C" { #endif /* * Class: Prompt * Method: getLine * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Prompt_getLine (JNIEnv * env, jobject obj, jstring prompt){ char buf[128]; const jbyte* str = (*env)->GetStringUTFChars(env, prompt, NULL); if(!str){ return NULL; } printf("%s", str); (*env)->ReleaseStringUTFChars(env,prompt,str); /*We assume here that the user does not type more than 127 characters */ scanf("%s", buf); return (*env)->NewStringUTF(env, buf); } #ifdef __cplusplus } #endif ~~~ 不要忘了检查GetStringUTFChars的返回值,因为Java虚拟机实现需要为UTF-8字符串分配内存空间,而这个内存分配操作是可能会失败的,当这种情况发生的时候,GetStringUTFChars就会返回空并抛出OutOfMemoryError错误,如果你还想着OutOfMemoryException,问下自己是不是最近写C#代码写多了。在第6章我们会介绍,从JNI中抛出一个异常是不同于从Java语言中抛出一个异常的。一个从JNI代码中抛出的异常不会自动改变当前原生C代码的执行流程。为了跳过C函数中剩下的代码,我们需要显式的使用return返回(以上代码中的return NULL)。在Java_Prompt_getLine返回之后,异常将会从Prompt.getLine的调用函数Prompt.main中抛出。