【问题标题】:How to get the Updated Size of Structure?Size of the Structure not getting Updated When I add values to dynamic array Fields如何获得结构的更新大小?当我将值添加到动态数组字段时,结构的大小未更新
【发布时间】:2010-08-09 19:23:23
【问题描述】:

这与我之前的question 有关,并且认为这将使它成为一个独立的问题,因为它会更有意义。

我已经创建了我的结构:

public struct Smb_Parameters
        {
            public byte WordCount;
            public ushort[] Words;
        }

当我尝试获取 Struct 的大小时不分配任何值,它返回 4 字节:

Smb_Parameters smbParameter = new Smb_Parameters();
int len1 = Marshal.SizeOf(smbParameter );
            MessageBox.Show(len1.ToString());

但是当我将值分配给结构字段时:

 Smb_Parameters smbParameter = new Smb_Parameters();
 string myString= "String  ll be converted to byte";
 smbParameter.WordCount=0x00;
 smbParameter .Words=Encoding.ASCII.GetBytes(myString);
 int len1 = Marshal.SizeOf(smbParameter );
 MessageBox.Show(len1.ToString());

现在仍然显示长度为 4 字节,但我需要更新后的大小。

【问题讨论】:

  • 你为什么将字数设置为 0?

标签: c# .net struct structure


【解决方案1】:

如果您希望像 unmanaged 类型一样获得大小,则需要提供有关其字段的一些信息(例如,数组的长度)。没有它,就不会考虑数组长度。

例如,

public struct Smb_Parameters1
{
    public byte WordCount; //1 byte
    public ushort[] Words; //4 bytes (a "pointer")
}
Marshal.SizeOf(typeof(Smb_Parameters1)); //8 (with padding)
//I don't see how you get 4 unless you are on a 16-bit system maybe

[StructLayout(LayoutKind.Sequential)]
public struct Smb_Parameters2
{
    public byte WordCount; //1 byte
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=10)]
    public ushort[] Words; //20 bytes (2 * 10 bytes)
}
Marshal.SizeOf(typeof(Smb_Parameters2)); //22 (with padding)

请注意,这些大小是固定的(就像在 C/C++ 程序中声明的一样)。 SizeOf() 报告的大小将只使用这些,而不考虑您在 Words 中存储的大小数组。

Smb_Parameters1 s1 = new Smb_Parameters1() { Words = new ushort[] { 0, 1, 2 } };
Smb_Parameters2 s2 = new Smb_Parameters2() { Words = new ushort[] { 0, 1, 2 } };
Marshal.SizeOf(s1); //8 bytes
Marshal.SizeOf(s2); //22 bytes

【讨论】:

  • 可能我得到 4 因为我使用的是 Marshal.SizeOf(Smb_Parameters1);不是 Marshal.SizeOf(typeof(Smb_Parameters1));我很确定虽然它不是 16 位系统
【解决方案2】:

Words 字段是一个数组,数组是引用类型。该结构实际​​上并不包含数组项,它只包含对数组的引用,该数组存储在其他地方(通常在堆上)。所以SizeOf 总是返回相同的大小,因为引用的大小不取决于该引用指向的对象的大小。

【讨论】:

  • 谢谢。有没有办法我们可以得到结构的实际大小。
  • 结构体的实际大小正是 Marshal.SizeOf 返回的...只是数组项不是结构体的一部分
【解决方案3】:

Marshal.SizeOf() 返回一个固定大小的类/结构。长度从不取决于传递的对象的内容。

你可以用Marshal.SizeOf(typeof(byte))+Marshal.SizeOf(typeof(ushort))*yourarraylength计算大小

另一种方法是使用BinaryFormatter 类将您的结构序列化为二进制形式。它返回一个字节数组。如果你看它的长度,你就会知道它的序列化大小。请注意,BinaryFormatter 的结果不容易被非 .net 语言读取,因为它的格式仅适用于 .net。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2014-11-11
    • 2019-04-19
    相关资源
    最近更新 更多