gpt4 book ai didi

android - JNI 调用将 jstring 转换为 char*

转载 作者:太空宇宙 更新时间:2023-11-03 10:46:25 25 4
gpt4 key购买 nike

我的 cpp 代码包含一个我希望转换为 const char* 的 jni 函数。这是我正在使用的代码

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)

我做错了什么?

最佳答案

您的代码和方法有几处不太正确:

  1. 如您所见,(env*)->JNIFunc(env,...) 在 C++ 中应该是 env->JNIFunc(...) .您的供应商(Google Android)的 jni.h 简化了 C++ 语法而不是 C 语法。
  2. 您没有调用与“固定”函数 (GetStringUTFChars) 相对应的“释放”函数 (ReleaseStringUTFChars)。这非常重要,因为固定对象会降低 JVM 垃圾收集器的内存效率。
  3. 您误解了 GetStringUTFChars 的最后一个参数。它是输出参数的指针。结果不是很有趣,所以传递 nullptr
  4. 您正在使用处理修改 UTF-8 编码(GetStringUTFChars 等)的 JNI 函数。应该没有必要使用该编码。 Java 类非常擅长转换编码。它们还可以让您控制当字符无法在目标编码中编码时发生的情况。 (默认是将其转换为 ?。)
  5. 将 JVM 对象引用 (jstring) 转换为指向单字节存储 (char*) 的指针的想法需要大量改进。您可能希望使用特定或操作系统默认编码将 JVM java.lang.String 中的字符复制为“ native ”字符串。 Java 字符串包含采用 UTF-16 编码的 Unicode 字符。 Android一般使用UTF-8编码的Unicode字符集。如果您还需要其他东西,您可以使用 Charset 对象指定它。
  6. 此外,在 C++ 中,使用 STL std::string 保存字符串的计数字节序列更为方便。你可以获得a pointer to a null-terminated buffer如果需要,来自 std::string

请务必阅读 Android 的 JNI Tips .

这是您的函数的实现,它允许供应商的 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,定义 native 方法以获取字节数组而不是字符串。

(当然,使用 GetStringUTFChars 的实现确实适用于 Unicode 字符串的某些子集,但为什么要施加深奥且不必要的限制?)

关于android - JNI 调用将 jstring 转换为 char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20536296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com