java调用DLL乱码问题

使用C++写了个dll,导出一个接口给java调用:

dll接口接收的字符串编码是GBK,java在传GBK字符串到DLL中时,发现中文是乱码

bool WINAPI JavaStr(char* szText, int textLen);

bool WINAPI JavaStr(char* szText, int textLen)
{
if (szText == NULL || textLen <= 0){
return false;
}

std::string strText(szText, textLen);
OutputDebugStringA("JavaStr:");
OutputDebugStringA(strText.c_str());
return true;
}

jna代码如下:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.win32.StdCallLibrary;

public interface FlashEncDec extends StdCallLibrary {
FlashEncDec INSTANCE = (FlashEncDec) Native.load("FlashEncDec", FlashEncDec.class);

// Optional: wraps every call to the native library in a
// synchronized block, limiting native calls to one at a time
// FlashEncDec SYNC_INSTANCE = (FlashEncDec)Native.synchronizedLibrary(INSTANCE);

public boolean JavaStr(String str, int strLen); // 使用String传参数,中文会参数乱码
public boolean JavaStr(byte[] str, int strLen); // 使用byte[]传参数,中文正常

}

调用例子代码如下:

String txtPath = "E:\\java.txt"; // 文件是UTF8编码
File file = new File(txtPath);
FileInputStream inputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader= new BufferedReader(inputStreamReader);

String utf8Str = bufferedReader.readLine();
String gbkStr = new String(utf8Str.getBytes("GBK"), "GBK"); // UTF8转成GBK
byte[] gbkBytes = utf8Str.getBytes("GBK");

FlashEncDec.INSTANCE.JavaStr(gbkStr, gbkStr.length()); // 传字符串C++接收时中文是乱码
FlashEncDec.INSTANCE.JavaStr(gbkBytes, gbkBytes.length); // 传字节数组C++接收中文正常

效果截图:

java jna cha*乱码问题_传参数

很明显cha*参数,在参数传递时,应该使用byte[],不然会产生中文乱码

该问题困扰了我一天,之前一直以为是不是我在java进行字符串编码转换时,转换错了?

各种字符串编码转换都试了一遍,就是有乱码。。。

后面想到,我直接创建个GBK编码的txt文件,然后使用GBK编码读取txt里面的内容,

把从GBK文件获取到的字符串传进DLL里面,这样可以确保参数是GBK编码的,这样做以后,发现还是乱码。。。

传GBK字符串,竟然还是乱码?这时就排除了字符串编码问题,

开始怀疑是不是JNA在调用DLL接口时改变了字符串编码?。。。

时间紧迫,不想去仔细分析JNA了,管不了那么多了,想到char*和byte[]是兼容类型,

那我直接传原始的byte[],对于byte[],JNA应该不会改变它吧,

想法很好,试试看,竟然正常了。。。

public boolean JavaStr(String str, int strLen);   // 使用String传参数,中文会参数乱码
public boolean JavaStr(byte[] str, int strLen); // 使用byte[]传参数,中文正常