国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

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

2020-01-24 00:22:39
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

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

如果dll文件中只包含一些基礎(chǔ)類型,那這個(gè)問(wèn)題可能可以被忽略,但是如果是組合類型(這個(gè)叫法也許不妥),如結(jié)構(gòu)體、類類型等,在其中的成員變量的長(zhǎng)度的申明正確與否將決定你對(duì)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ù)申明(一個(gè)c++程序引用另一個(gè)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); 

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

下面是我的c#的代碼

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

[StructLayout(LayoutKind.Sequential)]  public struct HSCAN_MSG  {     // UnmanagedType.ByValArray, [MarshalAs(UnmanagedType.U1)]這個(gè)非常重要,就是申明對(duì)應(yīng)類型和長(zhǎ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ù)申明(一個(gè)c++程序引用另一個(gè)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)識(shí),nEFF=1 時(shí)(擴(kuò)展幀),為29 位nEFF=0(標(biāo)準(zhǔn)幀)時(shí),為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ù)組指針的問(wèn)題詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 金昌市| 崇信县| 吉木萨尔县| 沅江市| 蛟河市| 阳原县| 庄浪县| 新野县| 梓潼县| 莱西市| 汉源县| 阿瓦提县| 七台河市| 吴旗县| 三台县| 万年县| 大化| 迭部县| 仙游县| 凤冈县| 济宁市| 安远县| 陆河县| 南和县| 大安市| 开平市| 民和| 祁阳县| 吴川市| 弋阳县| 当涂县| 大丰市| 镇赉县| 安龙县| 龙江县| 湟源县| 德格县| 盐边县| 内丘县| 阿图什市| 吴桥县|