成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#結構體使用淺析

開發 后端
C#結構體使用主要向你介紹了:在C#中調用C++或系統DLL是怎么樣子的操作。

C#結構體使用在C#中調用C++或系統DLL是比較常見的操作。

例如C++中定義的以下結構體:

  1. struct RCEStruct {   
  2.  int Event;  
  3.  int Flag;    
  4.  char User[40];   
  5. };  

C#結構體使用同時有一個公開方法:
 
extern "C" __declspec WORD CALLBACK GetStruct(RCEStruct* pEventStruc);

我們將它編譯為 MyCppDll.DLL

那么C#結構體使用上我們在C#中可以直接定義相同的結構體和引用GetStruct:

  1. [StructLayout(LayoutKind.Sequential)]   
  2. public struct RCEStruct {   
  3. public int Event;   
  4. public int Flag;   
  5. public char[40] User;   
  6. }   
  7.    
  8. [DllImport("MyCppDll.dll", CharSet=CharSet.Auto)]   
  9. public static extern int GetStruct(RCEStruct rce);  

注意C#里定義的結構體應該和C++里定義的一樣。這里如果是public string User就有可能出錯(具體我沒試過,不知道C#是否會自動將char[]轉變為string,另外還要注意,在C#中為User賦值時,長度不應超過40)。

通過這種方式我們就可以向C++傳遞或者獲得結構體。但一個限制就是必須在C#端主動調用GetStruct()

還有一種情況,與上一種相反,就是我們不是希望在C#中調用C++類庫,而是想在C++類庫中調用我們已經寫好的C#類庫。這在托管C++里是可以實現的。其中一個應用案例就是在為第三方系統寫C++插件的時候,我們必須在插件端主動調用C#類庫(前提是我們需要使用它,除非我們完全用C++代碼來寫這個插件)。

這樣的話我們的C#結構體使用應該是在C#類庫公開方法,例如:

  1. public struct RCEStruct {   
  2. public int Event;   
  3. public int Flag;   
  4. public string User;   
  5. }   
  6.    
  7. public void DoSomething(RCEStruct rce){   
  8. rce.Flag++;   

假定編譯成 MyCSharpDll.DLL

C#結構體使用之C++端代碼如下:

  1. #using ﹤mscorlib.dll﹥   
  2. #using ﹤CuteSuProc.dll﹥   
  3.    
  4. void SomeMethod(RCEStruct* pEventStruc){   
  5. // 將C++結構體賦值到C#結構體   
  6. MyCSharpDll::RCEStruct* csStruct;   
  7. csStruct-﹥Event = pEventStruc.Event;   
  8. csStruct-﹥Flag = pEventStruc.Flag;   
  9. // csStruct-﹥User ?? 將char轉換成string,在C++里如何處理?   
  10.    
  11. MyCSharpDll::DoSomething(csStruct);   
  12.    
  13. // 將C#結構體賦值到C++結構體   
  14. // 因為 pEventStruc 由外界傳入,被 DoSomething 方法修改后,可能仍需要外界知道   
  15. pEventStruc-﹥Event = csStruct.Event;   
  16. pEventStruc-﹥Flag = csStruct.Flag;   
  17. // pEventStruc-﹥User ?? 將string轉換成char[]   
  18.  
  19. }  

托管C++在處理.NET類庫時,有些細節是很繁瑣的,讓人覺得有些暈乎。譬如很多地方要加__gc修飾符。還有像數組,字符串的轉換都比較麻煩。所以上面代碼可能會有些小錯誤。但大致意思就是這樣。很明顯,這樣的做法非常麻煩。對結構體進行操作前,我們進行一次賦值,操作后,又進行一次賦值。

有沒有辦法直接讓C#操作原始的結構體呢?就像C#中操作C++一樣,不需要通過一個中間人?能不能直接這樣:

  1. #using ﹤mscorlib.dll﹥   
  2. #using ﹤CuteSuProc.dll﹥   
  3.    
  4. void SomeMethod(RCEStruct* pEventStruc){   
  5. MyCSharpDll::DoSomething(pEventStruc);   
  6. }  

答案是否定的。我們沒有辦法直接將C++里的 RCEStruct轉換為 C#里的 RCEStruct。

那么還剩一種方法,就是直接對內存進行操作。因為是結構體,他們肯定是保存在連續內存空間中的。

我們先來看看C#中如何操作內存,也就是非托管的數據。這需要引用System.Runtime.InteropServices命名空間。該命名空間下的Marshal的一些靜態方法提供了這樣的功能:

Marshal.ReadInt32()//從指定內存地址讀取4位

Marshal.PtrToStringAnsi()//從指定內存地址讀取字符串

Marshal.WriteInt32()//將整數寫到指定內存地址

Marshal.WriteByte()//將字符串寫到指定內存地址

我們來看看具體的C#結構體使用代碼:

  1. using System;   
  2. using System.Text;   
  3. using System.Runtime.InteropServices;   
  4.    
  5. internal sealed class RCEvent {   
  6. public int Event;   
  7. public int Flag;   
  8. public string User;   
  9. };   
  10.    
  11. internal sealed class RCEventAgent {   
  12. internal static RCEvent Read(IntPtr ptr){   
  13. RCEvent Event = new RCEvent();   
  14.    
  15. Event.Event = ReadEvent(ptr);   
  16. Event.Flag = ReadFlag(ptr);   
  17. Event.User = ReadUser(ptr);   
  18.    
  19. return Event;   
  20. }   
  21.    
  22. internal static int ReadEvent(IntPtr basePtr) {   
  23. return Marshal.ReadInt32(basePtr);   
  24. }   
  25. internal static int ReadFlag(IntPtr basePtr) {   
  26. return Marshal.ReadInt32(basePtr,4);   
  27. }   
  28. internal static string ReadUser(IntPtr basePtr) {   
  29. return Marshal.PtrToStringAnsi(  
  30. new IntPtr(basePtr.ToInt32() + 8));   
  31. }   
  32.    
  33. internal static void Write(ClientEvent Event,IntPtr ptr) {   
  34. WriteEvent(ptr,Event.Event);   
  35. WriteFlag(ptr,Event.Flag);   
  36. WriteUser(ptr,Event.User);   
  37. }   
  38.    
  39. internal static void WriteEvent(IntPtr basePtr,int value) {   
  40. Marshal.WriteInt32(basePtr,value);   
  41. }   
  42. internal static void WriteFlag(IntPtr basePtr,int flag) {   
  43. Marshal.WriteInt32(basePtr,4,flag);   
  44. }   
  45. internal static void WriteUser(IntPtr basePtr,string user) {   
  46. WriteString(basePtr,user,8,40);   
  47. }   
  48. private static void WriteString(  
  49. IntPtr basePtr,string value,int offset,int length) {   
  50. int pos = 0;   
  51. byte[] bytes = Encoding.Default.GetBytes(value);   
  52. while(pos ﹤ length) {   
  53. if (pos ﹤ bytes.Length)   
  54. Marshal.WriteByte(basePtr,offset,bytes[pos]);   
  55. else   
  56. Marshal.WriteByte(basePtr,offset,0);   
  57.    
  58. pos ++;   
  59. offset ++;   
  60. }   
  61. }   

C#結構體使用代碼解析:這樣我們就可以通過ReadEvent和WriteEvent直接在c#中處理該結構體?;蛘咄ㄟ^ ReadXXX() 和 WriteXXX() 直接修改其字段。

  1. public void DoSomething(IntPtr ptr){   
  2. RCEvent Event = RCEventAgent.Read(ptr);   
  3. Event.Flag ++;   
  4. RCEventAgent.Write(ptr, Event);   
  5.    
  6. // 或者以下代碼   
  7. // RCEventAgent.WriteFlag( ptr, RCEventAgent.ReadFlag(ptr) + 1 );   
  8. } C++中則可以直接將結構體地址傳給C#:   
  9. #using   ﹤mscorlib.dll﹥   
  10. #using   ﹤CuteSuProc.dll﹥   
  11.    
  12. void SomeMethod(RCEStruct* pEventStruc){   
  13. MyCSharpDll::DoSomething(pEventStruc);   
  14. }  

C#結構體使用方面的基本情況就向你介紹到這里,希望對你學習了解C#結構體使用有所幫助。

【編輯推薦】

  1. C#讀取Excel數據簡析
  2. C#讀取Excel遇到無法讀取的解決方法
  3. C#結構體的特點淺析
  4. C#結構體數組間的轉化淺析
  5. 解決C#結構體數組間的轉化
責任編輯:仲衡 來源: 博客園
相關推薦

2009-08-13 14:56:46

C#的結構體使用

2009-08-31 15:02:22

C#解析結構體指針

2009-08-13 11:18:50

C#結構體

2009-08-27 16:18:47

C#類C#結構體

2009-08-13 14:06:37

C#結構體結構體和類的區別

2009-08-13 13:03:52

C#結構體數組

2009-08-14 15:23:10

C#使用ErrorPr

2009-08-19 16:42:41

C#如何使用XML

2009-08-13 15:41:50

C#結構體指針

2009-09-11 11:27:38

AttributeUsC# Attribut

2009-08-25 16:29:33

C#使用sqlserv

2009-08-13 15:03:58

C#結構體變量

2009-08-14 11:05:28

C#語言的結構體

2009-08-13 14:46:03

C#結構體定義

2009-09-23 09:36:34

C#數組

2009-09-04 15:45:29

C#緩存流

2009-08-18 09:37:14

C#枚舉類型

2009-08-25 15:59:28

C#串口操作

2009-08-13 14:24:44

C#結構體構造函數

2009-08-17 18:34:50

C# ChangeCo
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久草视频在线播放 | 在线视频国产一区 | 天天干天天想 | 精品亚洲一区二区三区 | 亚洲电影中文字幕 | 日韩精品在线观看网站 | 中文字幕四虎 | 久久大香| 成人精品久久久 | 国产精品久久精品 | 精品日韩在线 | 亚洲精品一区二区 | 羞羞视频网站在线观看 | 中文字幕在线观看一区 | 好姑娘影视在线观看高清 | 在线观看h视频 | 日韩av电影院 | 日韩有码在线观看 | 狠狠狠| 欧美日韩中文字幕 | 欧美日韩视频在线第一区 | 欧美日韩在线成人 | 午夜无码国产理论在线 | 国产一二三区免费视频 | 欧美一区二区三区久久精品视 | 日韩欧美国产综合 | 国产第一亚洲 | 国产精品久久久久久久久久三级 | 巨大黑人极品videos精品 | 久久国产精品偷 | 国产精品自产av一区二区三区 | 91传媒在线观看 | 狠狠干狠狠操 | 国产三级一区二区三区 | 在线观看欧美一区 | 一区二区三区四区免费在线观看 | 欧美性大战久久久久久久蜜臀 | 免费黄视频网站 | 精品一级毛片 | 伊人久久综合 | av影片在线 |