C#呼叫c++Dll結構體陣列指標的問題
C#呼叫c++dll檔案是一件很麻煩的事情,首先面臨的是資料型別轉換的問題,相信經常做c#開發的都和我一樣把學校的那點c++底子都忘光了吧(語言特性類)。
網上有一大堆得轉換對應表,也有一大堆的轉換例項,但是都沒有強調一個更重要的問題,就是c#資料型別和c++資料型別佔記憶體長度的對應關係。
如果dll檔案中只包含一些基礎型別,那這個問題可能可以被忽略,但是如果是組合型別(這個叫法也許不妥),如結構體、類型別等,在其中的成員變數的長度的申明正確與否將決定你對dll檔案呼叫的成敗。
如有以下程式碼,其實不是dll檔案的原始碼,而是廠商給的c++例子程式碼
c++中的結構體申明
- typedef struct
- {
- unsigned char Port;
- unsigned long Id;
- unsigned char Ctrl;
- unsigned char pData[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)]
- publicstruct HSCAN_MSG
- {
-
// UnmanagedType.ByValArray, [MarshalAs(UnmanagedType.U1)]這個非常重要,就是申明對應型別和長度的
- [MarshalAs(UnmanagedType.U1)]
- publicbyte Port;
- [MarshalAs(UnmanagedType.U4)]
- publicuint nId;
- [MarshalAs(UnmanagedType.U1)]
- publicbyte nCtrl;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- publicbyte[] pData;
- };
c#函式申明
- [DllImport("HS2106API.dll")]
- publicstaticexternint 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
- {
- unsigned char Port;
- unsigned long Id;
- unsigned char Ctrl;
- unsigned char pData[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#中的結構體申明:
- [StructLayout(LayoutKind.Sequential)]
- publicstruct HSCAN_MSG
- {
- [MarshalAs(UnmanagedType.U1)]
- publicbyte Port;
- /// <summary>
- /// 節點標識,nEFF=1 時(擴充套件幀),為29 位nEFF=0(標準幀)時,為11 位;
- /// </summary>
- [MarshalAs(UnmanagedType.U4)]
- publicuint nId;
- [MarshalAs(UnmanagedType.U1)]
- publicbyte nCtrl;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- publicbyte[] pData;
- };
c#函式的呼叫:包含使用指標IntPtr替代結構體陣列和讀取IntPtr的方法
- HSCAN_MSG[] msg1 = new HSCAN_MSG[10];
- for (int i = 0; i < msg1.Length; i++)
- {
- msg1[i] = new HSCAN_MSG();
- msg1[i].pData = newbyte[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() + "幀資料";
- 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#呼叫c++Dll結構體陣列指標的問題
C#呼叫c++dll檔案是一件很麻煩的事情,首先面臨的是資料型別轉換的問題,相信經常做c#開發的都和我一樣把學校的那點c++底子都忘光了吧(語言特性類)。 網上有一大堆得轉換對應表,也有一大堆的轉換例項,但是都沒有強調一個更重要的問題,就是c#資料型別和c++資料型別佔
【C語言】用結構體陣列指標完成:有三個學生資訊,存放在結構體陣列中,要求輸出全部資訊
//用結構體陣列指標完成:有三個學生資訊,存放在結構體陣列中,要求輸出全部資訊 #include <stdio.h> struct Stu { int num; char name[2
c語言結構體陣列指標
#include<stdio.h> #define N 3 struct student { long int num; char name[20]; float score[3]; float aver; }; int main() {
C/C++動態自定義結構體陣列例項鍛鍊-學生成績排序
/************************************************************************/ /* 本程式是對動態記憶體、動態陣列、結構體、函式的綜合應用。 */ /***********************
【C語言】用結構體陣列完成:有5個學生(包括學號,姓名,成績),要求按照成績高低輸出學生資訊.
//用結構體陣列完成:有5個學生(包括學號,姓名,成績),要求按照成績高低輸出學生資訊 #include <stdio.h> struct Stu { int num; char na
C語言_指向結構體的指標_plusC14.4
#include<stdio.h> #define LEN 20 struct name {char first[LEN];char last[LEN]; }; struct guy {struct name handle;char favfood[LEN];c
c#呼叫C/C++ DLL,傳入指標陣列(指標指向自定的結構體)
來源:http://bbs.csdn.net/topics/380165851 依靠以下文章:解決問題。 、、、、、、、、、、、、、、、、、、、、 可以用Marshal.StruectToPtr哦。 、、、、、、、、、、、、、、 [StructLayout(Layo
結構體指標作函式引數(C# 呼叫C++ 的DLL)
1、C++結構體定義: #pragma pack(1) struct Person { #define Count_favoriteNumbers 6 int id; fl
C# 呼叫dll 封送結構體 結構體陣列
一. 結構體的傳遞 cpp 程式碼 #define JNAAPI extern "C" __declspec(dllexport) // C方式匯出函式 typedef struct { int osVersion; int majorVe
C#呼叫C++ 平臺呼叫P/Invoke 結構體--含有內建資料型別的一維、二維陣列、字串指標【六】
【1】結構體中含有內建資料型別的一維陣列 C++程式碼: typedef struct _testStru3 { int iValArrp[30]; WCHAR szChArr[30];
轉--C#呼叫C++DLL傳遞結構體陣列的終極解決方案
在專案開發時,要呼叫C++封裝的DLL,普通的型別C#上一般都對應,只要用DllImport傳入從DLL中引入函式就可以了。但是當傳遞的是結構體、結構體陣列或者結構體指標的時候,就會發現C#上沒有型別可以對應。這時怎麼辦,第一反應是C#也定義結構體,然後當成引數傳弟。然而,當
C#呼叫C/C++動態庫 封送結構體,結構體陣列
一. 結構體的傳遞 Cpp程式碼 #define JNAAPI extern "C" __declspec(dllexport) // C方式匯出函式 typedef struct { int osVersion;
C語言 一個例子說明結構體變數,結構體陣列和結構體指標
輸入三個學生的個人資訊 包含學號 姓名和三門學科的成績 輸出平均成績最高的學生的學號 姓名 各科成績以及平均成績 程式碼如下(譚浩強c程式設計的例子) #include<stdio.h> struct Student {int num;
5. C 結構體 陣列的指標 初始化 與 記憶體釋放
結構體如下: struct student{ Int num; Char* name; } Tom,*Lily; 1.如果定義成Tom的形式,不需要為結構體分配記憶體,但是需要對name
c語言指向結構體陣列的指標
c指標變數可以指向一個結構陣列,這時結構指標變數的值是整個結構陣列的首地址。結構指標變數也可指向結構陣列的一個元素,這時結構指標變數的值是該結構陣列元素的首地址。設ps為指向結構陣列的指標變數,則ps也指向該結構陣列的0號元素,ps+1指向1號元素,ps+i則指向i號
第22節 C語言結構體之結構體巢狀、結構體指標與結構體陣列的程式碼實現
結構體 #include <stdio.h> //第一步 struct Student { //學號 int no; //姓名 char name[20]; //性別 char
結構體陣列,結構體指標 (C,隨筆)
#include<stdlib.h> struct S { int num; }; struct S s; struct S ss[5]; #include<stdio.h>
C#呼叫C++ 平臺呼叫P/Invoke 結構體--輸入輸出引數、返回值、返出值、結構體陣列作為引數【五】
【1】結構體作為輸入輸出引數 C++程式碼: typedef struct _testStru1 { int iVal; char cVal; __int64 llVal; }testS
C++的陣列、結構體、指標三種複合型別知識點小總結
陣列、結構體、指標是C++的3種複合型別。陣列可以在一個數據物件中儲存多個不同型別的值,通過使用索引或下標,可以訪問陣列中的各個元素。結構體可以將多個不同型別的值儲存在同一個資料物件中,可以使用成員關
C語言——結構體與指標引用&結構體陣列與指標引用
接下來,程式的控制權交給Mutiline函式,進入函式Mutiline。在程式進入函式Mutiline之後,pPoints 指向oPoints的首地址,跟蹤程式表明此時變數pPoints的當前值為0X0F82。另外,由於陣列第一個元素oPoints[0]的地址與陣列的首地址相同。亦可以理解為此時pPoints