C 呼叫c Dll結構體陣列指標的問題

2021-05-26 16:45:59 字數 2532 閱讀 1687

c#呼叫c++dll檔案是一件很麻煩的事情,首先面臨的是資料型別轉換的問題,相信經常做c#開發的都和我一樣把學校的那點c++底子都忘光了吧(語言特性類)。

網上有一大堆得轉換對應表,也有一大堆的轉換例項,但是都沒有強調乙個更重要的問題,就是c#資料型別和c++資料型別佔記憶體長度的對應關係。

如果dll檔案中只包含一些基礎型別,那這個問題可能可以被忽略,但是如果是組合型別(這個叫法也許不妥),如結構體、類型別等,在其中的成員變數的長度的申明正確與否將決定你對dll檔案呼叫的成敗。

如有以下**,其實不是dll檔案的原始碼,而是廠商給的c++例子**

c++中的結構體申明 

typedef struct

unsigned charport;

unsigned longid;

unsigned charctrl;

unsigned charpdata[8];

}hscan_msg;

c++中的函式申明(乙個c++程式引用另乙個c++的dll檔案)

extern "c" int _stdcall hscan_sendcanmessage(unsigned char ndevice,unsigned char nport,hscan_msg *msg,int nlength); 

c++中的呼叫:

hscan_msg msg[100]; 

hscan_sendcanmessage(m_ndevice,m_nport,msg,nframes);

由上述**可見,msg是個結構體的陣列。

下面是我的c#的**

c#結構體申明:(申明成) 

[structlayout(layoutkind.sequential)]

public struct  hscan_msg

// unmanagedtype.byvalarray, [marshalas(unmanagedtype.u1)]這個非常重要,就是申明對應型別和長度的

[marshalas(unmanagedtype.u1)]

public byte port;

[marshalas(unmanagedtype.u4)]

public uint nid;

[marshalas(unmanagedtype.u1)]

public byte nctrl;

[marshalas(unmanagedtype.byvalarray, sizeconst = 8)]

public byte pdata;

c#函式申明

[dllimport("hs2106api.dll")]

public static extern int hscan_sendcanmessage(

byte ndevice, byte nport, hscan_msg pmsg, int nlength); 

c#函式呼叫

hscan_msg msg = new hscan_msg[1];//傳送緩衝區大小可根據需要設定;

for (int yy = 0; yy < msg.length; yy++)

msg[yy] = new hscan_msg();

//...結構體中的成員的例項化略

hscan_sendcanmessage(0x0, 0x0, msg, 1) 

那些只能用指標不能用結構體和類的地方

c++中的結構體申明 

typedef struct

hscan_msg;

c++中的函式申明(乙個c++程式引用另乙個c++的dll檔案)

extern "c" int _stdcall hscan_sendcanmessage(unsigned char ndevice,unsigned char nport,hscan_msg *msg,int nlength);

c#中的結構體申明:

[structlayout(layoutkind.sequential)]

public struct hscan_msg

; c#函式的呼叫:包含使用指標intptr替代結構體陣列和讀取intptr的方法

hscan_msg msg1 = new hscan_msg[10];

for (int i = 0; i < msg1.length; i++)

intptr ptarray = new intptr[1];

ptarray[0] = marshal.allochglobal(marshal.sizeof(typeof(hscan_msg)) * 10);

intptr pt = marshal.allochglobal(marshal.sizeof(typeof(hscan_msg)));

marshal.copy(ptarray, 0, pt, 1); 

int count = hscan_readcanmessage(0x0, 0,pt, 10);

textboxstatus.text += "\r\n" + "讀取0口:" + count.tostring() + "幀資料";

for (int j = 0; j < 10; j++)

C 呼叫c Dll結構體陣列指標的問題

c 呼叫c dll檔案是一件很麻煩的事情,首先面臨的是資料型別轉換的問題,相信經常做c 開發的都和我一樣把學校的那點c 底子都忘光了吧 語言特性類 網上有一大堆得轉換對應表,也有一大堆的轉換例項,但是都沒有強調乙個更重要的問題,就是c 資料型別和c 資料型別佔記憶體長度的對應關係。如果dll檔案中只...

C 呼叫C dll中的結構體的定義

為使用者定義的結構指定自定義封送處理 可以為傳遞到非託管函式或從非託管函式返回的結構和類的字段指定自定義封送處理屬性。通過向結構或類的字段中新增 marshalas屬性可以做到這一點。還必須使用 structlayout 屬性設定結構的布局,還可以控制字串成員的預設封送處理,並設定預設封裝大小。示例...

C 呼叫C dll 結構體引數傳遞問題

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