将字符串从 Java 传递到 JNI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4247002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing string from Java into JNI
提问by perumal316
I want to pass a string into the JNI I am writing which have to be assigned to a const char*. The below mentioned is how I have done it:
我想将一个字符串传递到我正在编写的 JNI 中,该字符串必须分配给一个 const char*。下面提到的是我是如何做到的:
JNI...(...,jstring jstr...){
const char* str = env->GetStringUTFChars(jstr,0);
env->ReleaseStringUTFChars(str,jstr,0);
}
But if i printf the const char* str after assigning to the jstring what I see is different as compared to when I assigned the str value directly in the JNI and printf from there.
但是,如果我在将 const char* str 分配给 jstring 之后打印了 const char* str ,则与我直接在 JNI 和 printf 中从那里分配 str 值时相比,我看到的是不同的。
Is this the correct way to do? Or is there any other way to assign a string from java to const char* in JNI ?
这是正确的做法吗?或者有没有其他方法可以将字符串从 java 分配给 JNI 中的 const char* ?
回答by Jigar Joshi
java code
代码
public static native double myMethod( String path);
C Code
C代码
JNIEXPORT jdouble JNICALL Java_your_package_structure_className_myMethod
(JNIEnv * env, jobject jobj, jstring pathObj) {
char * path;
path = (*env)->GetStringUTFChars( env, pathObj, NULL ) ;
回答by Vladimir Ivanov
All you do is correct. There is other way but to obtain wchar_t instead of char:
你所做的一切都是正确的。除了获得 wchar_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);
回答by Eduardo Costa
Actually, solution is simple: the last parameter of "GetStringUTFChars" is JNI_TRUE to send a copy. Since you are passing JNI_FALSE (0) and calling "ReleaseStringUTFChars", you are destroying the reference. What you see after "releasing" are random bytes from elsewhere in your application memory.
其实,解决办法很简单:“GetStringUTFChars”的最后一个参数是JNI_TRUE,发送一个副本。由于您正在传递 JNI_FALSE (0) 并调用“ReleaseStringUTFChars”,因此您正在破坏引用。“释放”后您看到的是来自应用程序内存中其他地方的随机字节。
Calling "GetStringUTFChars" with JNI_TRUE or removing the "ReleaseStringUTFChars" call will solve your problem.
使用 JNI_TRUE 调用“GetStringUTFChars”或删除“ReleaseStringUTFChars”调用将解决您的问题。
EDIT: Sorry about graveyard digging.
编辑:很抱歉挖墓地。
回答by Davood Falahati
As #Jigar explained:
正如#Jigar 解释的那样:
JNIEXPORT jdouble JNICALL Java_your_package_structure_className_myMethod
(JNIEnv * env, jobject jobj, jstring jstr) {
const char *path = (*env)->GetStringUTFChars( env, jstr , NULL ) ;
in order to get a jstring from java, one should write c++ method as below
为了从java获取jstring,应该编写如下c++方法
C++ code:
C++代码:
const char *path = env->GetStringUTFChars(jstr , NULL ) ;
UPDATE: As mentioned in comments, there was a mistake in the code. It's now fixed.
更新:正如评论中提到的,代码中有一个错误。现在已经修复了。
回答by prem kumar
JNIEXPORT jstring JNICALL Java_Hello_sayHi(JNIEnv *env, jobject obj, jstring string) {
const char *str = env->GetStringUTFChars(string, 0);
printf("%s", str);
}
回答by vijaycaimi
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()))