欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于C#調(diào)用c++Dll結(jié)構(gòu)體數(shù)組指針的問題詳解

 更新時間:2017年12月14日 14:44:29   作者:jadeflute  
下面小編就為大家分享一篇基于C#調(diào)用c++Dll結(jié)構(gòu)體數(shù)組指針的問題詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

C#調(diào)用c++dll文件是一件很麻煩的事情,首先面臨的是數(shù)據(jù)類型轉(zhuǎn)換的問題,相信經(jīng)常做c#開發(fā)的都和我一樣把學(xué)校的那點(diǎn)c++底子都忘光了吧(語言特性類)。

網(wǎng)上有一大堆得轉(zhuǎn)換對應(yīng)表,也有一大堆的轉(zhuǎn)換實(shí)例,但是都沒有強(qiáng)調(diào)一個更重要的問題,就是c#數(shù)據(jù)類型和c++數(shù)據(jù)類型占內(nèi)存長度的對應(yīng)關(guān)系。

如果dll文件中只包含一些基礎(chǔ)類型,那這個問題可能可以被忽略,但是如果是組合類型(這個叫法也許不妥),如結(jié)構(gòu)體、類類型等,在其中的成員變量的長度的申明正確與否將決定你對dll文件調(diào)用的成敗。

如有以下代碼,其實(shí)不是dll文件的源碼,而是廠商給的c++例子代碼

c++中的結(jié)構(gòu)體申明

typedef struct 
{ 
 unsigned char Port; 
 unsigned long Id; 
 unsigned char Ctrl; 
 unsigned char pData[8]; 
}HSCAN_MSG; 

c++中的函數(shù)申明(一個c++程序引用另一個c++的dll文件)

extern "C" int _stdcall HSCAN_SendCANMessage(unsigned char nDevice,unsigned char nPort,HSCAN_MSG *msg,int nLength);

c++中的調(diào)用:

.... 
HSCAN_MSG msg[100]; 
..... 
HSCAN_SendCANMessage(m_nDevice,m_nPort,msg,nFrames); 

由上述代碼可見,msg是個結(jié)構(gòu)體的數(shù)組。

下面是我的c#的代碼

c#結(jié)構(gòu)體申明:(申明成)

[StructLayout(LayoutKind.Sequential)] 
 public struct HSCAN_MSG 
 { 
    // UnmanagedType.ByValArray, [MarshalAs(UnmanagedType.U1)]這個非常重要,就是申明對應(yīng)類型和長度的 
 [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#函數(shù)申明

[DllImport("HS2106API.dll")] 
 public static extern int HSCAN_SendCANMessage( 
 byte nDevice, byte nPort, HSCAN_MSG[] pMsg, int nLength); 

C#函數(shù)調(diào)用

HSCAN_MSG[] msg = new HSCAN_MSG[1]; //發(fā)送緩沖區(qū)大小可根據(jù)需要設(shè)置; 
 for (int yy = 0; yy < msg.Length; yy++) 
 { 
 msg[yy] = new HSCAN_MSG(); 
 } 
    //...結(jié)構(gòu)體中的成員的實(shí)例化略 
    HSCAN_SendCANMessage(0x0, 0x0, msg, 1) 

那些只能用指針不能用結(jié)構(gòu)體和類的地方

c++中的結(jié)構(gòu)體申明

typedef struct 
{ 
 unsigned char Port; 
 unsigned long Id; 
 unsigned char Ctrl; 
 unsigned char pData[8]; 
}HSCAN_MSG; 

c++中的函數(shù)申明(一個c++程序引用另一個c++的dll文件)

extern "C" int _stdcall HSCAN_SendCANMessage(unsigned char nDevice,unsigned char nPort,HSCAN_MSG *msg,int nLength); 

c#中的結(jié)構(gòu)體申明:

[StructLayout(LayoutKind.Sequential)] 
 public struct HSCAN_MSG 
 { 
 [MarshalAs(UnmanagedType.U1)] 
 public byte Port; 
 /// <summary> 
 /// 節(jié)點(diǎn)標(biāo)識,nEFF=1 時(擴(kuò)展幀),為29 位nEFF=0(標(biāo)準(zhǔn)幀)時,為11 位; 
 /// </summary> 
 [MarshalAs(UnmanagedType.U4)] 
 public uint nId; 
 [MarshalAs(UnmanagedType.U1)] 
 public byte nCtrl; 
 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 
 public byte[] pData; 
 }; 

c#函數(shù)的調(diào)用:包含使用指針I(yè)ntPtr替代結(jié)構(gòu)體數(shù)組和讀取IntPtr的方法

HSCAN_MSG[] msg1 = new HSCAN_MSG[10]; 
 for (int i = 0; i < msg1.Length; i++) 
 { 
 msg1[i] = new HSCAN_MSG(); 
 msg1[i].pData = new byte[8]; 
 } 
 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() + "幀數(shù)據(jù)"; 
 for (int j = 0; j < 10; j++) 
 { 
 msg1[j] = 
 (HSCAN_MSG)Marshal.PtrToStructure((IntPtr)((UInt32)pt+ j * Marshal.SizeOf(typeof(HSCAN_MSG))) 
 , typeof(HSCAN_MSG)); 
 textBoxStatus.Text += "/r/n收到0口" + Convert.ToByte(msg1[j].pData[0]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[1]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[2]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[3]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[4]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[5]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[6]).ToString() 
 + "|" + Convert.ToByte(msg1[j].pData[7]).ToString(); 
 } 

以上這篇基于C#調(diào)用c++Dll結(jié)構(gòu)體數(shù)組指針的問題詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#使用正則表達(dá)式過濾html標(biāo)簽

    C#使用正則表達(dá)式過濾html標(biāo)簽

    最近在開發(fā)一個項(xiàng)目,其中有需求要求我們把一段html轉(zhuǎn)換為一般文本返回,使用正則表達(dá)式是明智的選擇,下面小編給介紹下C#使用正則表達(dá)式過濾html標(biāo)簽,需要的朋友參考下
    2016-08-08
  • C#中隱藏TabControl選項(xiàng)卡標(biāo)簽的解決方案

    C#中隱藏TabControl選項(xiàng)卡標(biāo)簽的解決方案

    這篇文章主要介紹了C#中隱藏TabControl選項(xiàng)卡標(biāo)簽的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • c# 操作word寫入特殊字符的實(shí)例

    c# 操作word寫入特殊字符的實(shí)例

    這篇文章主要介紹了c# 操作word寫入特殊字符的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C#中WPF依賴屬性的正確學(xué)習(xí)方法

    C#中WPF依賴屬性的正確學(xué)習(xí)方法

    這篇文章主要介紹了C#中WPF依賴屬性的正確學(xué)習(xí)方法 ,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • C#實(shí)現(xiàn)EPL?II格式打印與打印測試

    C#實(shí)現(xiàn)EPL?II格式打印與打印測試

    這篇文章介紹了C#實(shí)現(xiàn)EPL?II格式打印與打印測試的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#串口連接的讀取和發(fā)送詳解

    C#串口連接的讀取和發(fā)送詳解

    這篇文章主要給大家介紹了關(guān)于C#串口連接的讀取和發(fā)送的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解c# 類型轉(zhuǎn)換

    詳解c# 類型轉(zhuǎn)換

    這篇文章主要介紹了c# 類型轉(zhuǎn)換的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以學(xué)習(xí)
    2020-07-07
  • C#實(shí)現(xiàn)簡易計(jì)算器

    C#實(shí)現(xiàn)簡易計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C#把寫好的類編譯成dll文件的操作方法

    C#把寫好的類編譯成dll文件的操作方法

    在C#中,DLL文件是一種可重用的代碼庫,它包含了已編譯的函數(shù)、類、數(shù)據(jù)和資源,DLL文件可以被多個應(yīng)用程序共享和重用,這樣可以提高代碼的復(fù)用性和可維護(hù)性,所以本文給大家介紹了C#如何把寫好的類編譯成dll文件,需要的朋友可以參考下
    2024-09-09
  • C#?SetWindowPos函數(shù)實(shí)例詳解

    C#?SetWindowPos函數(shù)實(shí)例詳解

    在C#中,SetWindowPos函數(shù)用于設(shè)置窗口的位置和大小,這篇文章主要介紹了C#?SetWindowPos函數(shù)實(shí)例詳解,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03

最新評論