JNI调用将jstring转换为char*
JNI call convert jstring to char*
我的cpp代码包含一个jni函数,我希望将其转换为const char*。这是我正在使用的代码
extern "C" {
void Java_com_sek_test_JNITest_printSomething(JNIEnv * env, jclass cl, jstring str) {
const char* mystring = env->GetStringUTFChars(env, str, 0);
PingoScreen::notify();
}
我得到一个错误
no matching function for call to '_JNIEnv::GetStringUTFChars(JNIEnv*&, _jstring*&, int)
我做错了什么?
您的代码和方法有几点不太正确:
- 正如您所发现的,
(env*)->JNIFunc(env,...)
应该是C++中的env->JNIFunc(...)
。您的供应商(Google Android的)jni.h简化了C++语法而不是C语法 - 您没有调用与"钉扎"函数(GetStringUTFChars)相对应的"Release"函数(ReleaseStringUTFChar)。这一点非常重要,因为固定对象降低了JVM垃圾收集器的内存效率
- 你误解了
GetStringUTFChars
的最后论点。它是一个输出参数的指针。结果不是很有趣,所以通过nullptr
- 您使用的JNI函数处理修改的UTF-8编码(
GetStringUTFChars
等人)。应该没有必要使用这种编码。Java类非常能够转换编码。它们还让您可以控制当无法在目标编码中对角色进行编码时会发生什么。(默认情况是将其转换为?
。) - 将JVM对象引用(
jstring
)转换为指向单字节存储(char*
)的指针的想法需要大量改进。您可能希望使用特定或操作系统默认编码将JVMjava.lang.String
中的字符复制到"本机"字符串。Java字符串包含使用UTF-16编码的Unicode字符。Android通常使用Unicode字符集和UTF-8编码。如果您需要其他东西,可以使用Charset
对象指定它 - 此外,在C++中,使用STL
std::string
来保存字符串的计数字节序列更方便。如果需要的话,您可以从std::string
中获取一个指向空终止缓冲区的指针
请务必阅读Android的JNI提示。
以下是您的函数的实现,它允许供应商的JVM实现选择目标编码(对于Android来说是UTF-8):
extern "C" JNIEXPORT void Java_com_sek_test_JNITest_printSomething
(JNIEnv * env, jclass cl, jstring str) {
// TODO check for JVM exceptions where appropriate
// javap -s -public java.lang.String | egrep -A 2 "getBytes"
const auto stringClass = env->FindClass("java/lang/String");
const auto getBytes = env->GetMethodID(stringClass, "getBytes", "()[B");
const auto stringJbytes = (jbyteArray) env->CallObjectMethod(str, getBytes);
const auto length = env->GetArrayLength(stringJbytes);
const auto pBytes = env->GetByteArrayElements(stringJbytes, nullptr);
std::string s((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
const auto pChars = s.c_str(); // if you really do need a pointer
}
然而,我可能会在Java端调用String.getBytes
,将本机方法定义为使用字节数组而不是字符串。
(当然,使用GetStringUTFChars的实现确实适用于Unicode字符串的某些子集,但为什么要施加一个深奥而不必要的限制?)
根据文档,
GetStringUTFCharsconst jbyte*GetStringUTFChars(JNIEnv*env,jboolean*isCopy);
返回一个指向字节数组的指针,该数组表示修改后的UTF-8编码中的字符串。此数组在ReleaseStringUTFChars()发布之前一直有效。
如果isCopy不为NULL,则如果进行了复制,则*isCopy设置为JNI_TRUE;或者如果没有进行复制则将其设置为JNI_ FALSE。
所以最后一个参数应该是jboolean;
尝试。。。更改此行
const char* mystring = env->GetStringUTFChars(env, str, 0);
至
const char *mystring = (*env)->GetStringUTFChars(env, str, 0);
希望它能起作用:)
相关文章:
- 将无符号char*转换为std::istream*C++
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 将函数参数"const char*"转换为"std::string_view"是
- C ++如何在使用"tolower"时将char转换为int
- 有没有办法在C++的赋值中将"char**"转换为"double"?
- JavaCPP 错误:无法将参数"1"的"char*"转换为"Abc*
- 为什么从 char 转换为 std::byte 可能是未定义的行为?
- 如何在虚幻引擎4中将char*转换为TCHAR?
- C++:将模板类型 char 转换为 std::string
- strcmp/char* 转换无法按预期工作
- C++中的SQLite char*转换
- 无法从 const char* 转换为 const char *&
- 在 C++ 中将 char 转换为 int,而无需符号位传播
- 如果必须包含西里尔字符,如何将 char* 转换为 std::string?
- 试图使用strCMP时的char转换错误
- 无法从'const char *'转换为'LPCTSTR'
- 将 std::vector<char> 转换为字符* 会导致字符缺陷
- 使用 static_cast 将 char 转换为 int c++
- 如何在 C++(MFC) 中将 char* 转换为 LPCTSTR
- 无法将const char转换为字符串构造字符串