C 呼叫C C 動態庫 封送結構體,結構體陣列

2021-06-18 03:45:07 字數 3377 閱讀 8615

一. 結構體的傳遞

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(

refosinfo info);  

public

static

extern

bool

getversionref(

refosinfo 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,

intnlen);  

呼叫**:

c#**

/*** c#介面,對於包含陣列型別,只能傳遞intptr

*/[dllimport("jnalib.dll"

, entrypoint = 

"getversionarray"

)]  

public

static

extern

bool

getversionarray(intptr p, 

intnlen);    

// 源目標引數

osinfo infos = new

osinfo[2];  

for(

inti = 0; 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(

inti = 0; i 

szversion:"

, infos[i].osversion, infos[i].szversion);  

}  

三. 複雜結構體的傳遞

cpp**

typedef

struct

student;  

// class中包含結構體陣列型別

typedef

struct

class;  

// 傳入複雜結構體測試

jnaapi int

getclass(class *pclass,

intlen);  

cpp**

// 介面定義 

[dllimport("jnalib.dll"

, entrypoint = 

"getclass"

)]  

public

static

extern

intgetclass(intptr pv,

intlen);  

// 結構體定義

//student

[structlayout(layoutkind.sequential)]  

public

struct

student  

//class

[structlayout(layoutkind.sequential)]  

public

struct

class  

// 呼叫複雜結構體測試

intsize = marshal.sizeof(typeof(class)) * 50;  

intptr pbuff = marshal.allochglobal(size); //直接分配50個元素的空間,比marshal.copy方便多了

getclass(pbuff, 50);  

class pclass = new

class[50];  

for(

inti = 0; i 

marshal.freehglobal(pbuff); //釋放記憶體

C 呼叫dll 封送結構體 結構體陣列

一.結構體的傳遞 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 c 結構體呼叫

1 最近做專案遇到,c 呼叫c dll裡的函式需要傳遞結構體引數,發現這個並不是簡單的在c 裡定義相應的結構體就可以的,下面以乙個例子來說明解決的辦法,c 中的函式和結構體如下 uint msec set igr gen cfg int port,igr gen t igr gen typedef ...