zoukankan      html  css  js  c++  java
  • 枚举位域结构综合实验

    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.aspx
    
    namespace 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}	DI={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();
            }
        }
    }
  • 相关阅读:
    poj 1743 Musical Theme 后缀数组
    poj 1743 Musical Theme 后缀数组
    cf 432D Prefixes and Suffixes kmp
    cf 432D Prefixes and Suffixes kmp
    hdu Data Structure? 线段树
    关于position和anchorPoint之间的关系
    ios POST 信息
    CALayers的代码示例
    CALayers详解
    ios中得sqlite使用基础
  • 原文地址:https://www.cnblogs.com/flaaash/p/5326430.html
Copyright © 2011-2022 走看看