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

C#結(jié)構(gòu)體使用淺析

開發(fā) 后端
C#結(jié)構(gòu)體使用主要向你介紹了:在C#中調(diào)用C++或系統(tǒng)DLL是怎么樣子的操作。

C#結(jié)構(gòu)體使用在C#中調(diào)用C++或系統(tǒng)DLL是比較常見的操作。

例如C++中定義的以下結(jié)構(gòu)體:

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

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

我們將它編譯為 MyCppDll.DLL

那么C#結(jié)構(gòu)體使用上我們在C#中可以直接定義相同的結(jié)構(gòu)體和引用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#里定義的結(jié)構(gòu)體應(yīng)該和C++里定義的一樣。這里如果是public string User就有可能出錯(具體我沒試過,不知道C#是否會自動將char[]轉(zhuǎn)變?yōu)閟tring,另外還要注意,在C#中為User賦值時,長度不應(yīng)超過40)。

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

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

這樣的話我們的C#結(jié)構(gòu)體使用應(yīng)該是在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#結(jié)構(gòu)體使用之C++端代碼如下:

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

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

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

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

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

那么還剩一種方法,就是直接對內(nèi)存進行操作。因為是結(jié)構(gòu)體,他們肯定是保存在連續(xù)內(nèi)存空間中的。

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

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

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

Marshal.WriteInt32()//將整數(shù)寫到指定內(nèi)存地址

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

我們來看看具體的C#結(jié)構(gòu)體使用代碼:

  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#結(jié)構(gòu)體使用代碼解析:這樣我們就可以通過ReadEvent和WriteEvent直接在c#中處理該結(jié)構(gòu)體。或者通過 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++中則可以直接將結(jié)構(gòu)體地址傳給C#:   
  9. #using   ﹤mscorlib.dll﹥   
  10. #using   ﹤CuteSuProc.dll﹥   
  11.    
  12. void SomeMethod(RCEStruct* pEventStruc){   
  13. MyCSharpDll::DoSomething(pEventStruc);   
  14. }  

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

【編輯推薦】

  1. C#讀取Excel數(shù)據(jù)簡析
  2. C#讀取Excel遇到無法讀取的解決方法
  3. C#結(jié)構(gòu)體的特點淺析
  4. C#結(jié)構(gòu)體數(shù)組間的轉(zhuǎn)化淺析
  5. 解決C#結(jié)構(gòu)體數(shù)組間的轉(zhuǎn)化
責任編輯:仲衡 來源: 博客園
相關(guān)推薦

2009-08-13 14:56:46

C#的結(jié)構(gòu)體使用

2009-08-31 15:02:22

C#解析結(jié)構(gòu)體指針

2009-08-13 11:18:50

C#結(jié)構(gòu)體

2009-08-27 16:18:47

C#類C#結(jié)構(gòu)體

2009-08-13 13:03:52

C#結(jié)構(gòu)體數(shù)組

2009-08-13 14:06:37

C#結(jié)構(gòu)體結(jié)構(gòu)體和類的區(qū)別

2009-08-14 15:23:10

C#使用ErrorPr

2009-09-11 11:27:38

AttributeUsC# Attribut

2009-08-25 16:29:33

C#使用sqlserv

2009-08-19 16:42:41

C#如何使用XML

2009-08-13 15:41:50

C#結(jié)構(gòu)體指針

2009-08-14 11:05:28

C#語言的結(jié)構(gòu)體

2009-08-13 14:46:03

C#結(jié)構(gòu)體定義

2009-08-13 15:03:58

C#結(jié)構(gòu)體變量

2009-09-23 09:36:34

C#數(shù)組

2009-08-18 09:37:14

C#枚舉類型

2009-08-25 15:59:28

C#串口操作

2009-09-04 15:45:29

C#緩存流

2009-08-13 14:24:44

C#結(jié)構(gòu)體構(gòu)造函數(shù)

2009-08-07 17:25:37

C# SortedLi
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: av免费网站在线观看 | 美女拍拍拍网站 | 日日夜夜天天久久 | 国产精品成人在线播放 | 午夜视频免费在线观看 | 久久成人久久 | 伊人久久综合影院 | 国产91一区| 色综网 | 免费同性女女aaa免费网站 | 日韩中文一区二区 | 国产精品色av | 亚洲综合五月天婷婷 | 精品美女视频在线观看免费软件 | 国产一区二区精品在线观看 | 精品久久久久久久久久久久 | 成人片免费看 | 日韩国产一区二区三区 | 毛片在线免费 | 国内自拍偷拍视频 | 特黄特色大片免费视频观看 | 国产小视频在线 | 福利片在线观看 | 日韩欧美高清dvd碟片 | 中文一区二区 | 欧美影院 | 精品91久久| 一区二区免费在线 | 日韩成人av在线 | 一区二区三区成人 | 国产欧美一区二区三区免费 | 国产精品美女www爽爽爽视频 | 欧美国产精品一区二区三区 | 国产农村一级国产农村 | 亚洲欧美日本国产 | 成人免费看片又大又黄 | 中文字幕蜜臀av | www久久国产 | 男人天堂久久久 | 欧美精品久久 | 亚洲一区二区三区四区五区中文 |