標籤:
1.枚舉項和數值,字串如何互相轉換?2.結構和byte[]數組間如何互相轉換? 這在通訊上普遍使用!
3.位域在工控上DIO控制普遍使用,如何借鑒.
OK,上代碼!
using System;using System.Runtime.InteropServices;//http://www.cnblogs.com/pato/archive/2011/08/15/2139705.html//https://msdn.microsoft.com/zh-cn/library/asx0thw2%28v=vs.110%29.aspxnamespace EnumStructDemo{ /// <summary> /// 測量類型:儀迪檢測裝置測量的類型 /// </summary> public enum MeasureType : byte { ITEM_NULL = 0, //空 ITEM_NY = 1, //耐壓 ITEM_JD = 2, //接地 ITEM_JY = 3, //絕緣 ITEM_XL = 4, //泄漏 ITEM_GL = 5, //功率 ITEM_QD = 6, //啟動 ITEM_KD = 7 //開短 } /// <summary> /// Binary flag, flag enum. /// 二進位位標誌,一個枚舉執行個體包含多個枚舉值 /// 輸入控制訊號:到達位置,測量結束 /// </summary> [System.Flags()] public enum DigitalIN : byte { PositionOK = 0x01, idiMeasureFinish = 0x02, } /// <summary> /// 輸出控制訊號:儀迪裝置開始測量,啟動傳動點擊,點亮警示燈 /// </summary> [System.Flags()] public enum DigitalOut : byte { idiStart = 0x01, //first bit is true, others is false chuandong = 0x02, //second bit is true,... light = 0x04, //third bit is true,.... } /// <summary> /// 儀迪命令資料幀結構定義 /// </summary> public struct Frame { public byte Head; //0.幀頭 ‘I‘ public byte Protocal; //1.協議編號 ‘1‘ public byte AddrHigh; //2-3.郵寄地址高位在前,佔用2位元組:0~16383 public byte AddrLow; public byte bytCount; //4.本幀總位元組數 public byte Reserve; //5.保留,總是0 public byte Command; //6.主命令編號** public byte frameEnd; //7.幀尾,總是‘D‘ public byte chkSum; //8.校正和,所有位元組和的低位元組 public void Display() { } } /// <summary> /// struct to byte /// </summary> /// <param name="obj">truct object</param> /// <returns>string array</returns> public class StructConvert { /// <summary> /// 根據傳入的結構對象,返回對應的位元組數組的引用. /// </summary> /// <param name="obj">傳入對象</param> /// <returns>託管位元組數組</returns> public static byte[] StructToBytes(object obj) { int size = Marshal.SizeOf(obj); byte[] bytes = new byte[size];//在託管堆上分配位元組數組 //Allocates memory from the unmanaged memory of the process by using the pointer to the specified number of bytes. IntPtr structPtr = Marshal.AllocHGlobal(size); //Marshals data from a managed object to an unmanaged block of memory. //從託管對象obj封裝資料到非託管記憶體塊 Marshal.StructureToPtr(obj, structPtr, false); //Copies data from an unmanaged memory pointer to a managed 8-bit unsigned integer array. Marshal.Copy(structPtr, bytes, 0, size); Marshal.FreeHGlobal(structPtr); return bytes; } /// <summary> /// (StructName)convert.BytesToStruct(bytes, StructName.GetType()); /// </summary> /// <param name="bytes">byte array</param> /// <param name="structType">struct type</param> /// <returns>the converted struct </returns> public static object BytesToStruct(byte[] bytes, Type structType, int indexFrom = 0) { //結構的大小總是>=位元組數組, 拷貝位元組數組到結構,取位元組數組大小合適 int sizeStruct = Marshal.SizeOf(structType); int sizeBytes = bytes.Length; //通過使用指定的位元組數,從進程的非託管記憶體中分配記憶體。分配目標對象緩衝區 IntPtr structPtr = Marshal.AllocHGlobal(sizeStruct); //將資料從一維託管 8 位不帶正負號的整數數組複製到非託管記憶體指標。拷貝bytes到緩衝區 Marshal.Copy(bytes, indexFrom, structPtr, sizeBytes); //將資料從非託管記憶體塊封送到新分配的指定類型的託管對象,傳回託管對象的引用. 非託管記憶體塊可銷毀! //Marshals data from an unmanaged block of memory to a [newly allocated managed object] of the specified type. object objStruct = Marshal.PtrToStructure(structPtr, structType); //釋放以前從進程的非託管記憶體中分配的記憶體。 //Frees memory previously allocated from the unmanaged memory of the process. Marshal.FreeHGlobal(structPtr); return objStruct; } } class Program { static void Main(string[] args) { //*************枚舉測試*** foreach (var item in Enum.GetNames(typeof(MeasureType))) Console.WriteLine(item); //根據數值獲得枚舉對象,接收儀器資料後,分析測試資料的類型 MeasureType meas = (MeasureType)1;//1代表耐壓 meas = (MeasureType)Enum.Parse(typeof(MeasureType), "ITEM_NY", ignoreCase: true); //擷取枚舉對象的[數值],串口發送指令時可用枚舉項代表命令類型 byte jd = (byte)MeasureType.ITEM_JD;//接地是2 //測試枚舉項是否為指定標識,如是否為耐壓測試 bool ny = meas.HasFlag(MeasureType.ITEM_NY); Console.WriteLine("jd={0},ny={1}", jd, ny);//jd = 2,ny = True //*************位域測試*** DigitalOut DI = DigitalOut.light | DigitalOut.chuandong; Console.WriteLine("{0}\tDI={1}", DI, (byte)DI);//chuandong, light DI = 6 if ((DI & DigitalOut.idiStart) > 0) Console.WriteLine("啟動儀迪測試..."); //*************結構測試*** Frame frame = new Frame();//結構初始化,實值型別為0,參考型別為null UInt16 a = 5; byte b = 0xf1; int c = 0xf1f2; Int64 d = c; int size = Marshal.SizeOf(frame); size = Marshal.SizeOf(a);//2 //size = Marshal.SizeOf(DI);//Error! size = Marshal.SizeOf(b);//1 size = Marshal.SizeOf(c);//4 size = Marshal.SizeOf(d);//8 byte[] bytMeasStart = { 0x49, 0x31, 0x00, 0x01, 0x08, 0x00, 0x00, 0x44, 0xC7 }; frame = (Frame)StructConvert.BytesToStruct(bytMeasStart, frame.GetType()); byte[] bytNew = StructConvert.StructToBytes(frame); //frame.chkSum = 199, bytNew[8] = 199 Console.WriteLine("frame.chkSum={0}, bytNew[8]={1}", frame.chkSum, bytNew[8]); Console.ReadKey(); } }}
枚舉\位域\結構綜合實驗