前言 {#前言}
JNA就是针对java调用C++动态库开发的jar包程序,使java调用c++动态库变得非常简单
JNA主要负责:
- 接口调用 - 将C++接口转化成java方法
- 参数转化 - 将C++类型参数转化成java数据类型
JNA乱码出现原因 {#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 中将值赋给此指针变量,然后通过此指针变量获取值。