当前位置: 代码迷 >> C# >> c#结构体大小的计算,该如何处理
  详细解决方案

c#结构体大小的计算,该如何处理

热度:41   发布时间:2016-05-05 04:35:24.0
c#结构体大小的计算
结构体定义如下
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TMsgHeadInfo
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public char[] MsgCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public char[] MsgType;
            public byte SenderType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public char[] Sender;
            public byte ReceiverType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public char[] Receiver;
            public int TotalLength;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public char[] VerifyCode;

            public TMsgHeadInfo(int MsgLength)
            {
                MsgCode = new char[2];
                MsgType = new char[2];
                SenderType = 1;
                Sender = new char[6];
                ReceiverType = 4;
                Receiver = new char[6];
                TotalLength = MsgLength;
                VerifyCode = new char[32];
            }
        }

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct TDevInfo
        {
            public byte DevType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public char[] DevCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
            public char[] CheckTime;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public char[] ErrorStr;
            public Int32 CheckError;

            public TDevInfo(byte ADevType)
            {
                DevType = ADevType;
                DevCode = new char[10];
                CheckTime = new char[14];
                ErrorStr = new char[20];
                CheckError = 0;
            }
        }

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TLabelContent
        {
            public int PosX;
            public int PosY;
            public int Flag;
            public int Flv;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
            public char[] FileName;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
            public char[] strContent;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
            public char[] strColor;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
            public char[] strBkColor;
            public int Space;
            public int Font;
            public int FontHeight;
            public int FontWidth;

            public TLabelContent(int AFlag)
            {
                PosX = 0;
                PosY = 0;
                Flag = AFlag;
                Flv = 0;
                FileName = new char[255];
                strContent = new char[255];
                strColor = new char[12];
                strBkColor = new char[12];
                Space = 0;
                Font = 0;
                FontHeight = 0;
                FontWidth = 0;
            }
        }

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TPlayList
        {
            public int ActTime;
            public int Action;
            public int Speed;
            public int ListNum;
            public TLabelContent[] Content;

            public TPlayList(int count)
            {
                ActTime = 0;
                Action = 0;
                Speed = 0;
                ListNum = count;
                Content = new TLabelContent[count];
            }
        }
        //下发节目单     
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TPlayListInfo
        {
            public byte DevType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public char[] DevCode;
            public int Page;
            public TPlayList[] PlayList;

            public TPlayListInfo(int count)
            {
                DevType = 1;
                DevCode = new char[10];
                Page = 0;
                PlayList = new TPlayList[count];
            }
        }
        //下发报文     
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TPlayListMsg
        {
            public TMsgHeadInfo MsgHead;
            public TPlayListInfo PlayListInfo;

            public TPlayListMsg(int count)
            {
                MsgHead = new TMsgHeadInfo();
                PlayListInfo = new TPlayListInfo();
            }
        }

为什么 

TPlayListMsg msg = new TPlayListMsg();
MessageBox.Show(Marshal.SizeOf(msg).ToString());

获得的大小是77,如何才能正确计算出结构体的大小呢
------解决思路----------------------
没看懂
public TPlayListMsg(int count)这个构造函数没用上?
你用的是默认的隐藏无参数构造函数实例化的结构体啊
------解决思路----------------------
看了一下代码,你最终的结构体大小明显和传入的count有关
而这个count你根本没有传入
------解决思路----------------------
public TPlayList[] PlayList; 问题在于这里吧,他认不到了。
------解决思路----------------------
既然你的构造函数带参数
你应该TPlayListMsg msg = new TPlayListMsg(10);啊
为什么先用无参数的构造函数实例化,再到结构体里面去循环赋值?
这结构体真的是你自己写的吗,怎么感觉你自己都不会用的
------解决思路----------------------

知道为啥是固定的77了

他是只算了
 public TMsgHeadInfo MsgHead; 
public TPlayListInfo PlayListInfo;

这两个结构里面的基本类型的字段 
然而里面的
public TLabelContent[] Content;
TPlayList[] PlayList 这个他实际只是取得 这个Content,PlayList的指针地址的长度也就是8
而你要取的是每个Content与PlayList实际New 后每个项的长度之和。。。

这个搞不了
------解决思路----------------------
77是对的,算法如下:
2+2+1+6+1+6+4+32+(这是TMsgHeadInfo的长度)
1+10+4+8(这是TPlayListInfo的长度)
正好是77,一点没错。

从你的发言中,可以看出你根本不会VC++,所以写的C#代码也是半桶水。
在VC++里面,数组是定长的,就不存在可变长度数组,定义的时候必须指定长度,但是你看你定义的TPlayListInfo中,“public TPlayList[] PlayList;”就没指定长度,你希望在运行时动态给长度,这种做法在C++里面你试试,你能定义一个运行时动态改变长度的结构体吗?除非用指针,否则变长数组肯定不行。因此这里在计算时,系统用了Inptr的长度,也就是8字节。
------解决思路----------------------
引用:
为什么加上[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]大小依然是77

你编译了没?长度明明是输出28529的,居然说是77。我就不上图了,你自己认证检查下程序的修改日期,是不是执行的老的程序。
  相关解决方案