虽然之前也用过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查看器看一下
本文详细介绍了如何通过Java Native Access (JNA) 库实现Java代码与C++ DLL文件之间的交互,包括结构体传递的不同方式、指针与引用参数的使用等,并提供了完整的示例代码。
468

被折叠的 条评论
为什么被折叠?



