jna调用dll得类型转换,特别注意,char**是String[]需要设置数组长度得,需要跟dll程序中保持一致
不设置相同的数组长度会报错,或者长度设置不一致会报
Bounds exceeds available space : size=1048576, offset=1048577
其他的**应该也是类似得
c++调用dll库的例子
typedef char* (__cdecl * pfuncAll)(char*,int,char **,int);
//加载DLL文件
hDLL = LoadLibrary(TEXT("fisher.dll"));
//获取DLL文件中名称为pfunc的函数地址
pfuncAll funcAll=(pfuncAll)GetProcAddress(hDLL, "method_All");//混合判别
char **ab=(char**)malloc(3 * sizeof(char*));
for (int i = 0; i < 3; i++)
{
ab[i] = (char*)malloc((20 + 1) * sizeof(char));
}
java调用这种带char**的方法的例子
public interface MyLibraryMapper extends Library {
public String method_All(String tableName, int sampleId, String[] ptrArray, int num);
}
//调用实例
String[] strArray = {"", "",""};
String result = myLibrary.method_All(ch,id,strArray,2);
补充
最后调用成功后一定要手动释放内存,不然短时间第二次调用会报内存溢出的错误
strArray = null; // 手动释放内存
2023.4.18补充
所有传入的参数都需要手动释放内存,不会都会报内存溢出
完整代码
@Repository
public class MyLibraryDataOperate {
@SneakyThrows
public Object useMyLibraryDll(String dllPath, String funcName, ArrayList<Object> paramArray) {
String user=""; //username
String pswd=""; //password
String host="";
String database = ""; //数据库名称
int port=3306; //server port
String sampledatatable=""; //判别数据所在数据表的名称
int start=3;
int stop=8;
int id = Integer.valueOf(paramArray.get(1).toString());
if (funcName.equals("method_one")) {
MyLibraryMapper myLibrary = Native.load(dllPath, MyLibraryMapper.class);
myLibrary.initSql(user,pswd,host,database,port,sampledatatable,start,stop);
String ch = paramArray.get(0).toString(); //判别数据库
String result = myLibrary.method_one(ch,id);
ch = null;
myLibrary = null;
return result;
} else if (funcName.equals("method_two")){
MyLibraryMapper myLibrary = Native.load(dllPath, MyLibraryMapper.class);
myLibrary.initSql(user,pswd,host,database,port,sampledatatable,start,stop);
String ch = paramArray.get(0).toString(); //判别数据库
String result = myLibrary.method_two(ch,id);
ch = null;
myLibrary = null;
return result;
}
else if (funcName.equals("method_All")){
MyLibraryMapper myLibrary = Native.load(dllPath, MyLibraryMapper.class);
myLibrary.initSql(user,pswd,host,database,port,sampledatatable,start,stop);
String[] strArray = {paramArray.get(2).toString(), paramArray.get(3).toString(),""};
String ch = paramArray.get(0).toString(); //判别数据库
String result = myLibrary.method_All(ch,id,strArray,2);
strArray = null; // 手动释放内存
ch = null;
myLibrary = null;
return result;
}else {
return null;
}
}
}
public class test {
public static void main(String[] args) {
MyLibraryDataOperate myLibraryDataOperate1 = new MyLibraryDataOperate();
MyLibraryDataOperate myLibraryDataOperate2 = new MyLibraryDataOperate();
MyLibraryDataOperate myLibraryDataOperate3= new MyLibraryDataOperate();
ArrayList<Object> list = new ArrayList<Object>();
list.add("sample88");
list.add(530);
System.setProperty("jna.encoding", "GBK");
String result1 = myLibraryDataOperate1.useMyLibraryDll("D:\\fisher","method_one",list).toString();
myLibraryDataOperate1=null;
System.out.println(result1);
list.add(result1);
String result2 = myLibraryDataOperate2.useMyLibraryDll("D:\\fisher","method_two",list).toString();
myLibraryDataOperate2=null;
list.add(result2);
System.out.println(result2);
String result3 = myLibraryDataOperate3.useMyLibraryDll("D:\\fisher","method_All",list).toString();
myLibraryDataOperate3=null;
System.out.println(result3);
}
}