将字符串从Java传递到JNI
我想将一个字符串传递到我正在编写的JNI中,该字符串必须分配给const char*。 以下是我是如何做到这一点的:将字符串从Java传递到JNI,java,java-native-interface,Java,Java Native Interface,我想将一个字符串传递到我正在编写的JNI中,该字符串必须分配给const char*。 以下是我是如何做到这一点的: JNI...(...,jstring jstr...){ const char* str = env->GetStringUTFChars(jstr,0); env->ReleaseStringUTFChars(str,jstr,0); } 但是如果我在分配给jstring之后打印const char*str,我看到的与我直接在JNI中分配str值并从那里打印时
JNI...(...,jstring jstr...){
const char* str = env->GetStringUTFChars(jstr,0);
env->ReleaseStringUTFChars(str,jstr,0);
}
但是如果我在分配给jstring之后打印const char*str,我看到的与我直接在JNI中分配str值并从那里打印时不同
这是正确的方法吗?或者,在JNI中,有没有其他方法可以将java中的字符串分配给const char* java代码
public static native double myMethod( String path);
C代码
JNIEXPORT jdouble JNICALL Java_your_package_structure_className_myMethod
(JNIEnv * env, jobject jobj, jstring pathObj) {
char * path;
path = (*env)->GetStringUTFChars( env, pathObj, NULL ) ;
- 你所做的一切都是正确的。
除了获取wchar\u t而不是char之外,还有其他方法:
const wchar_t * utf16 = (wchar_t *)env->GetStringChars(bytes, NULL);
size_t length = (size_t)env->GetStringLength(bytes);
...
env->ReleaseStringChars(bytes, (jchar *)utf16);
实际上,解决方案很简单:“GetStringUTFChars”的最后一个参数是JNI_TRUE,用于发送副本。由于您正在传递JNI_FALSE(0)并调用“ReleaseStringUTFChars”,因此您正在销毁引用。“释放”后,您看到的是应用程序内存中其他位置的随机字节 用JNI_TRUE调用“GetStringUTFChars”或删除“ReleaseStringUTFChars”调用将解决您的问题 编辑:很抱歉挖掘墓地。正如#吉加解释的那样:
JNIEXPORT jdouble JNICALL Java_your_package_structure_className_myMethod
(JNIEnv * env, jobject jobj, jstring jstr) {
const char *path = (*env)->GetStringUTFChars( env, jstr , NULL ) ;
<>为了从java中获取JStk,应该编写C++方法,如
C++代码:
const char *path = env->GetStringUTFChars(jstr , NULL ) ;
更新:
正如评论中提到的,代码中有一个错误。现在已修复。您能提供(java)之前和(c)之后的字符串吗?文档中的参数看起来有误。这里有多个错误。首先,若方法是静态的,那个么就不提供jobject,而提供jclass。其次,(*env)不正确,只需要env->Get。。。第三,GetStringUTFChars没有将env作为参数。@Vladimir Ivano签出文档,这是工作代码@VladimirIvanov This:(*env)->方法(Env,C是正确的,EnV-->是JNI的C++方式。你刚刚做了一天……从4小时开始尝试,所有类似的解决方案都没有用,但是,这一个……!非常感谢!参考链接似乎真的被破坏了。埃默里?好吧,他说“const char*”的内容已更改,而不是指针本身。我指的是您所说的:“应用程序内存中其他位置的随机字节”。这意味着
str
的值已更改,这是不可能的,因为它不是通过引用传递的。它是一个C指针。在释放之前,它指向一些有用的内容。如果释放并保留它,它就是一个指针如果在C中使用'char a;char*b=&a+rand()%10000;printf(“%s\n”,b);”,您会得到他描述的相同症状(我称之为“随机”,因为您无法预测它是什么)。-1“GetStringUTFChars”的最后一个参数是一个输出值(指向布尔的指针)。传递什么并不重要,它只会告诉您它是否是副本(请参阅上的文档)。此外,如果删除“ReleaseStringUTFChars”,则会给应用程序添加内存泄漏。应该做的是在调用release函数之前充分利用数据,或者在发布之前复制数据。在C
版本上,path
是char*
而在C++
版本中path
是const char*
-我很困惑-用户应该释放char数组,还是它是指向某个内部jstring
字段的指针,将由Java处理?@SomethingSomething感谢您的关注。问题已经解决。您可以尝试这种方法,它肯定会有所帮助。您应该始终向支持您的回答欢迎使用Stack Overflow!虽然此代码片段可能会解决此问题,但确实有助于提高您文章的质量。请记住,您将为将来的读者回答此问题,而这些人可能不知道您的代码建议的原因。同时,请尽量不要用解释性命令挤满您的代码nts,这降低了代码和解释的可读性!
JNIEXPORT jstring JNICALL Java_Hello_sayHi(JNIEnv *env, jobject obj, jstring string) {
const char *str = env->GetStringUTFChars(string, 0);
printf("%s", str);
}
there are several ways but the best i got by converting const char * to c++ string
and then to jbyteArray, and its easy to conversion of byteArray to UTF-8 on java
side.
C++ side:
const char* string = propertyValue;
std::string str = string;
jbyteArray array = env->NewByteArray(str.length());
env->SetByteArrayRegion(array,0,str.length(),(jbyte*)str.c_str());
return array;
java/kotlin side:
String((array), Charset.defaultCharset()))