我一直在尝试调用具有以下签名的C函数
int changeFoo(L_TCHAR* pszFileSrc){....}
在我的JNI调用中,我的方法如下所示:
JNIEXPORT jint JNICALL Java_com_me_L_AFoo(JNIEnv * env, jclass jclass, jstring pSrc)
{
jint retValue = -100;
retValue = changeFoo(pSrc);
return retValue;
}
我在visual studio中收到以下错误。
错误1错误C2664:'L_FileConvert':无法将参数1从'jstring'转换为'L_TCHAR *'c:\ Ayusman \ Work \ MyVCpp \ LTExampleDll \ LTExampleDll \ LTExampleMain.cpp 46 LTExampleDll
当我查看L_TCHAR *的定义时
这是我在头文件中获得的内容(按顺序):
typedef TCHAR L_TCHAR;
typedef WCHAR TCHAR,*PTCHAR;
typedef wchar_t WCHAR; //wc, 16 bit UNICODE char
我在java上工作,这是我正在尝试构建的JNI应用程序。 任何人都可以帮助我如何正确地转换它?
答案 0 :(得分:2)
您必须手动转换字符串。这是一些(更正的)示例代码:
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "Foo.h"
#define SURROGATE_MASK 0xD800
#define is_surrogate(c) (((c) & SURROGATE_MASK) == SURROGATE_MASK)
static wchar_t calculate_code_point(wchar_t surrogate_1, wchar_t surrogate_2);
JNIEXPORT void JNICALL
Java_Foo_foo(JNIEnv *env, jobject obj, jstring bar) {
const jchar *chars = NULL;
wchar_t *result = NULL;
size_t len;
size_t source_pos, result_pos;
if (bar == NULL) {
return;
}
len = (*env)->GetStringLength(env, bar);
chars = (*env)->GetStringChars(env, bar, NULL);
if (chars == NULL) {
return;
}
result = (wchar_t *) malloc(sizeof(wchar_t) * (len + 1));
source_pos = result_pos = 0;
while (source_pos < len) {
wchar_t curr_char = chars[source_pos++];
if (is_surrogate(curr_char)) {
wchar_t surrogate_1 = curr_char;
wchar_t surrogate_2 = chars[source_pos++];
curr_char = calculate_code_point(surrogate_1, surrogate_2);
}
result[result_pos++] = curr_char;
}
result[result_pos] = L'\0';
(*env)->ReleaseStringChars(env, bar, chars);
printf("%ls\n", result);
free(result);
}
/**
* Based on example code from http://unicode.org/faq/utf_bom.hmtl
*/
static wchar_t calculate_code_point(wchar_t high_surrogate, wchar_t low_surrogate) {
wchar_t x = (high_surrogate & ((1 << 6) - 1)) <<10 | low_surrogate & ((1 << 10) - 1);
wchar_t w = (high_surrogate >> 6) & ((1 << 5) - 1);
wchar_t u = w + 1;
return u << 16 | x;
}
请注意,此代码仅适用于使用Java 5或更高版本且wchar_t数据类型长度为四个字节的情况。如果您使用的是Java 1.4或更低版本,或者您的wchar_t数据类型长度为两个字节,那么您不必担心代理项。
此代码还省略了一些基本的错误检查,并假设该对中的第一个代理是高阶代理(在我的机器上就是这种情况)。你可以明确地告诉哪个代理人是高阶代理人,哪个代理人是各自价值的低阶代理人。高阶代理在0xD800和0xDBFF之间,包括端点。低阶代理在0xDC00和0xDFFF之间,包括端点。如果您发现高阶代理人未与低阶代理人或低阶代理人配对而未与高阶代理人配对,则该字符串编码错误。