jna對結構體、指標、引用、拷貝引數傳遞的使用
阿新 • • 發佈:2019-01-31
雖然之前也用過jna,但是對於結構體的傳遞、指標引數數與返回值、引用引數與返回值、拷貝變數傳遞使用沒有總結。
先上生成DLL程式碼:
//dllTest.h
#ifndef DLLTEST_H #define 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); }; #endif
// dllTest.cpp : 定義 DLL 應用程式的匯出函式。 // #include "stdafx.h" #include "dllTest.h" __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 : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include "stdlib.h" #include "dllTest.h" 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;
@Override
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檢視器看一下