一.
結構體的傳遞
cpp **
#define jnaapi extern "c" __declspec(dllexport) // c方式匯出函式
typedef struct
osinfo;
// 1. 獲取版本資訊(傳遞結構體指標)
jnaapi bool getversionptr( osinfo *info );
// 2.獲取版本資訊(傳遞結構體引用)
jnaapi bool getversionref(osinfo &info);
可以通過二種方式來呼叫:
c#**
// osinfo定義
[structlayout(layoutkind.sequential)]
public struct osinfo
1. 方式一(傳入
結構體引用
),在c#中,結構體是以傳值方式傳遞,類才是以傳位址方式傳遞,加關鍵字ref即可. c端傳遞了兩種不同型別的引數,都可以通過引用來解決.
c#**
[dllimport("jnalib.dll", entrypoint = "getversionptr")]
public static extern bool getversionptr(ref osinfo info);
public static extern bool getversionref(ref osinfo info);
2. 方式二(
傳入intptr
(平台通用指標))
cpp**
intptr pv = marshal.allochglobal(148); //結構體在使用時一定要分配空間(4*sizeof(int)+128)
marshal.writeint32(pv,148); //向記憶體塊裡寫入數值
if (getversionptr(pv)) //直接以非託管記憶體塊位址為引數
", marshal.readint32(pv, 0));
console.writeline("--major:",marshal.readint32(pv, 4)); //移動4個位元組
console.writeline("--buildnum: " + marshal.readint32(pv, 12));
console.writeline("--szversion: "+marshal.ptrtostringansi((intptr)(pv.toint32()+20)));
}marshal.freehglobal(pv); //處理完記得釋放記憶體
二.
結構體陣列的傳遞
cpp**
// 傳遞結構體指標
jnaapi bool getversionarray(osinfo *info,int nlen);
呼叫**:
c#**
/**
* c#介面,對於包含陣列型別,只能傳遞intptr
*/ [dllimport("jnalib.dll", entrypoint = "getversionarray")]
public static extern bool getversionarray(intptr p, int nlen);
// 源目標引數
osinfo infos = new osinfo[2];
for (int i = 0; i < infos.length; i++)
intptr ptarr = new intptr[1];
ptarr[0] = marshal.allochglobal(marshal.sizeof(typeof(osinfo)) * 2); //分配包含兩個元素的陣列
intptr pt = marshal.allochglobal(marshal.sizeof(typeof(osinfo)));
marshal.copy(ptarr, 0, pt, 1); //拷貝指標陣列
getversionarray(pt, 2); //呼叫
//還原成結構體陣列
for (int i = 0; i < 2; i++)
szversion:", infos[i].osversion, infos[i].szversion);
}
三.
複雜結構體的傳遞
1. 輸出引數,結構體作為指標傳出
cpp**
typedef struct
student;
// class中包含結構體陣列型別
typedef struct
class;
// 傳入複雜結構體測試
jnaapi int getclass(class *pclass,int len);
c#**
// 介面定義
[dllimport("jnalib.dll", entrypoint = "getclass")]
public static extern int getclass(intptr pv,int len);
// 結構體定義
// student
[structlayout(layoutkind.sequential)]
public struct student
// class
[structlayout(layoutkind.sequential)]
public struct class
// 呼叫複雜結構體測試
int size = marshal.sizeof(typeof(class)) * 50;
intptr pbuff = marshal.allochglobal(size); // 直接分配50個元素的空間,比marshal.copy方便多了
getclass(pbuff, 50);
class pclass = new class[50];
for (int i = 0; i < 50; i++)
marshal.freehglobal(pbuff); // 釋放記憶體
2. 輸入引數, 給複雜結構體賦值後作為輸入引數傳入
對於比較大的結構體指標,無法直接應用結構體型別,轉化成intptr型別, 此時需要將原生型別轉化為指標,並給指標賦值
呼叫方法: marshal.structuretoptr(stu, ptr1, true)
C 呼叫C C 動態庫 封送結構體,結構體陣列
一.結構體的傳遞 cpp define jnaapi extern c declspec dllexport c方式匯出函式 typedef struct osinfo 1.獲取版本資訊 傳遞結構體指標 jnaapi bool getversionptr osinfo info 2.獲取版本資訊 傳...
平台呼叫 結構的封送
關於結構的封送,先看乙個類 structlayoutattribute 該類的作用是,允許控制記憶體中類或結構的資料字段的物理布局。該類的層次結構為 system.object system.attributesystem.runtime.interopservices.structlayoutat...
結構體巢狀結構體 C語言結構體
希望今年夏天的遺憾能成為你秋天的驚喜。網易雲熱評 一 結構體概念 可以簡單理解為把不同資料型別放到一起的陣列 二 結構體宣告與初始化 1 先宣告結構體型別再定義變數 2 同時定義變數 3 直接定義結構體型別變數 include include include include struct aiyou...