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();
            }
        }
    }
  • 相关阅读:
    Linux 系统的启动过程
    Oracle中row_number()、rank()、dense_rank() 的区别
    Java 动态打印菱形代码之for循环的使用
    Oracle 体系结构chapter2
    Oracle 11g 概述 chaper1
    go解决ctrl+鼠标左键或F12失效问题
    解决unrecognized import path "golang.org/x/sys/windows"问题
    设计规范
    性能分析
    用IDEA导入项目时,项目中的SpringBoot注解无法识别
  • 原文地址:https://www.cnblogs.com/flaaash/p/5326430.html
Copyright © 2011-2022 走看看