虽然之前也用过jna,但是对于结构体的传递、指针参数数与返回值、引用参数与返回值、拷贝变量传递使用没有总结。
先上生成DLL代码:
//dllTest.h
-
-
-
-
struct myStruct
-
{
-
int a;
-
int b;
-
};
-
-
extern "C"{
-
__declspec(dllexport) int addNormal(myStruct ms);
-
__declspec(dllexport) void addPrt(myStruct *ms, int *ret);
-
__declspec(dllexport) int addRef(myStruct &ms);
-
};
-
-
// dllTest.cpp : 定义 DLL 应用程序的导出函数。
-
//
-
-
-
-
-
-
__declspec(dllexport) int addNormal(myStruct ms){
-
return ms.b + ms.a;
-
}
-
-
__declspec(dllexport) void addPrt(myStruct *ms, int *ret){
-
*ret = ms->a + ms->b + 1;
-
}
-
-
__declspec(dllexport) int addRef(myStruct &ms){
-
return ms.a + ms.b + 2;
-
}
生成的DLL用查看器查看:
-
// dllUse.cpp : 定义控制台应用程序的入口点。
-
//
-
-
-
-
-
-
-
int _tmain( int argc, _TCHAR* argv[])
-
{
-
myStruct ms;
-
ms.a = 1;
-
ms.b = 2;
-
-
myStruct *pms = &ms;
-
-
printf( "%d",addNormal(ms));
-
-
int sum;
-
addPrt(&ms,&sum);
-
-
printf( "%d",sum);
-
-
printf( "%d\n",addRef(ms));
-
-
system( "Pause");
-
return 0;
-
}
运行结果:
——————————————————————————————————————————————————————————
java调用代码:
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import com.sun.jna.Library;
-
import com.sun.jna.Native;
-
import com.sun.jna.Structure;
-
import com.sun.jna.ptr.IntByReference;
-
-
-
public interface dllTestApi extends Library {
-
-
public static dllTestApi dta = (dllTestApi)Native.loadLibrary( "dllTest", dllTestApi.class);
-
-
public static class myStructur extends Structure{
-
public static class ByReference extends myStructur implements Structure.ByReference{
-
}
-
-
public static class ByValue extends myStructur implements Structure.ByValue{
-
}
-
-
public int a;
-
public int b;
-
-
-
protected List<String> getFieldOrder() {
-
List<String> Field = new ArrayList<String>();
-
Field.add( "a");
-
Field.add( "b");
-
-
return Field;
-
}
-
}
-
-
int addNormal(myStructur.ByValue ms);
-
void addPrt(myStructur.ByReference pms,IntByReference sum);
-
int addRef(myStructur.ByReference rms);
-
}
-
import com.sun.jna.ptr.IntByReference;
-
-
public class test {
-
-
public static void main(String[] args){
-
-
dllTestApi.myStructur.ByReference pmysStructur = new dllTestApi.myStructur.ByReference();
-
pmysStructur.a = 1;
-
pmysStructur.b = 3;
-
-
IntByReference ib = new IntByReference();
-
dllTestApi.dta.addPrt(pmysStructur,ib);
-
System.out.println(ib.getValue());
-
-
System.out.println(dllTestApi.dta.addRef(pmysStructur));
-
-
dllTestApi.myStructur.ByValue vmysStructur = new dllTestApi.myStructur.ByValue();
-
vmysStructur.a = 1;
-
vmysStructur.b = 3;
-
-
System.out.println(dllTestApi.dta.addNormal(vmysStructur));
-
}
-
}
运行结果:
结论:
1.只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种
2.指针和引用的传递使用ByReference
2.拷贝参数传递使用ByValue
如果编译好的dll在jna中提示不能找到该函数,请注意是否使用了extern “C” 关键字。或者使用dll查看器看一下