jna对结构体、指针、引用、拷贝参数传递的使用

虽然之前也用过jna,但是对于结构体的传递、指针参数数与返回值、引用参数与返回值、拷贝变量传递使用没有总结。

先上生成DLL代码:

//dllTest.h
  1. #ifndef DLLTEST_H
  2. #define DLLTEST_H
  3. struct myStruct
  4. {
  5. int a;
  6. int b;
  7. };
  8. extern "C"{
  9. __declspec(dllexport) int addNormal(myStruct ms);
  10. __declspec(dllexport) void addPrt(myStruct *ms, int *ret);
  11. __declspec(dllexport) int addRef(myStruct &ms);
  12. };
  13. #endif

  1. // dllTest.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "stdafx.h"
  4. #include "dllTest.h"
  5. __declspec(dllexport) int addNormal(myStruct ms){
  6. return ms.b + ms.a;
  7. }
  8. __declspec(dllexport) void addPrt(myStruct *ms, int *ret){
  9. *ret = ms->a + ms->b + 1;
  10. }
  11. __declspec(dllexport) int addRef(myStruct &ms){
  12. return ms.a + ms.b + 2;
  13. }


生成的DLL用查看器查看:



C++测试代码:

  1. // dllUse.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "stdlib.h"
  5. #include "dllTest.h"
  6. int _tmain( int argc, _TCHAR* argv[])
  7. {
  8. myStruct ms;
  9. ms.a = 1;
  10. ms.b = 2;
  11. myStruct *pms = &ms;
  12. printf( "%d",addNormal(ms));
  13. int sum;
  14. addPrt(&ms,&sum);
  15. printf( "%d",sum);
  16. printf( "%d\n",addRef(ms));
  17. system( "Pause");
  18. return 0;
  19. }

运行结果:




——————————————————————————————————————————————————————————

java调用代码:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import com.sun.jna.Library;
  4. import com.sun.jna.Native;
  5. import com.sun.jna.Structure;
  6. import com.sun.jna.ptr.IntByReference;
  7. public interface dllTestApi extends Library {
  8. public static dllTestApi dta = (dllTestApi)Native.loadLibrary( "dllTest", dllTestApi.class);
  9. public static class myStructur extends Structure{
  10. public static class ByReference extends myStructur implements Structure.ByReference{
  11. }
  12. public static class ByValue extends myStructur implements Structure.ByValue{
  13. }
  14. public int a;
  15. public int b;
  16. @Override
  17. protected List<String> getFieldOrder() {
  18. List<String> Field = new ArrayList<String>();
  19. Field.add( "a");
  20. Field.add( "b");
  21. return Field;
  22. }
  23. }
  24. int addNormal(myStructur.ByValue ms);
  25. void addPrt(myStructur.ByReference pms,IntByReference sum);
  26. int addRef(myStructur.ByReference rms);
  27. }


  1. import com.sun.jna.ptr.IntByReference;
  2. public class test {
  3. public static void main(String[] args){
  4. dllTestApi.myStructur.ByReference pmysStructur = new dllTestApi.myStructur.ByReference();
  5. pmysStructur.a = 1;
  6. pmysStructur.b = 3;
  7. IntByReference ib = new IntByReference();
  8. dllTestApi.dta.addPrt(pmysStructur,ib);
  9. System.out.println(ib.getValue());
  10. System.out.println(dllTestApi.dta.addRef(pmysStructur));
  11. dllTestApi.myStructur.ByValue vmysStructur = new dllTestApi.myStructur.ByValue();
  12. vmysStructur.a = 1;
  13. vmysStructur.b = 3;
  14. System.out.println(dllTestApi.dta.addNormal(vmysStructur));
  15. }
  16. }


运行结果:




结论:

1.只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种

2.指针引用的传递使用ByReference

2.拷贝参数传递使用ByValue


如果编译好的dll在jna中提示不能找到该函数,请注意是否使用了extern “C” 关键字。或者使用dll查看器看一下

猜你喜欢

转载自blog.csdn.net/wuqianjing/article/details/80867588