我的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)
我做错了什么?
答案 0 :(得分:4)
对于您的代码和方法,有几件事情并不完全正确:
(env*)->JNIFunc(env,...)
在C ++中应该是env->JNIFunc(...)
。您的供应商(Google Android)jni.h简化了C语法的C ++语法。GetStringUTFChars
的最后一个论点。它是输出参数的指针。结果不是很有趣所以通过nullptr
。 GetStringUTFChars
等)的JNI函数。应该没有必要使用该编码。 Java类非常有能力转换编码。它们还可以控制无法在目标编码中编码字符时发生的情况。 (默认是将其转换为?
。)jstring
)转换为指向一个字节存储(char*
)的想法需要大量改进。您可能希望使用特定或OS默认编码将JVM java.lang.String
中的字符复制到“本机”字符串。 Java字符串具有UTF-16编码的Unicode字符。 Android通常使用带有UTF-8编码的Unicode字符集。如果您还需要其他内容,可以使用Charset
对象指定它。std::string
来保存字符串的计数字节序列会更方便。如果需要,您可以从std::string
获得a pointer to a null-terminated buffer。请务必阅读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
,定义采用字节数组而不是字符串的本机方法。
(当然,使用GetStringUTFChars的实现确实适用于Unicode字符串的某些子集,但为什么会施加深奥和不必要的限制?)
答案 1 :(得分:2)
根据文件,
GetStringUTFChars const jbyte * GetStringUTFChars(JNIEnv * env,jstring string, jboolean * isCopy);
返回一个指向字节数组的指针,该字节数组表示修改后的UTF-8编码中的字符串。此数组在ReleaseStringUTFChars()发布之前有效。
如果isCopy不为NULL,则如果进行了复制,则* isCopy设置为JNI_TRUE;如果没有复制,则设置为JNI_FALSE。
所以最后一个参数应该是一个jboolean;
答案 2 :(得分:1)
尝试...更改此行
const char* mystring = env->GetStringUTFChars(env, str, 0);
到
const char *mystring = (*env)->GetStringUTFChars(env, str, 0);
希望它有效:)