将字符串从 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:59:22  来源:igfitidea点击:

Passing string from Java into JNI

javajava-native-interface

提问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()))