前言

JNA就是针对java调用C++动态库开发的jar包程序,使java调用c++动态库变得非常简单

JNA主要负责:

  • 接口调用 - 将C++接口转化成java方法
  • 参数转化 - 将C++类型参数转化成java数据类型

JNA乱码出现原因

JNA在对c++的char*和JAVA的String进行互相转换时候,针对C++字符数组编码设定错误导致乱码的出现

解决办法

第一种解决思路

只需要更改下JNA中字符串编码即可,该编码指定了String转换成char*时使用的字符编码

1
2
3
4
5
//c++ char* GBK编码时
System.setProperty("jna.encoding","GBK");

//c++ char* UTF8编码时
System.setProperty("jna.encoding","UTF-8");

第二种解决思路

JNA提供了一个宽字符字符串WString,当然c++接口参数类型要使用wchar_t,这样WString就可以无缝转wchar_t了,不用做任何修改,也绝对不会乱码。

第三种解决思路

1
2
3
4
void test(char* buf){
char temp[100] = "Hello World!" ;
memcpy(buf, temp, strlen(temp)) ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DLLUtil {
private static final String path = ConfigUtil.get("dllpath") ;
private static final String name = ConfigUtil.get("dllname") ;

public interface CLibrary extends Library{
//定义并初始化接口的静态变量
CLibrary Instance=(CLibrary)Native.loadLibrary(path + File.separator + name, CLibrary.class);

void test(Pointer p);
}

public static void main(String[] args) {
System.setProperty("jna.encoding", "GBK");
// 首先定义指针,开辟内存空间,这里的内存空间根据返回的字符串来决定
Pointer p = new Memory(20);
CLibrary.Instance.test(p);
System.out.println(p.getString(0, "GBK"));
}
}

通过 Java 获取 char 字符串,必须要通过 Java 传入一个 com.sun.jna.Pointer 指针变量,然后在 DLL 中将值赋给此指针变量,然后通过此指针变量获取值。