Как получить обновленный размер структуры? Размер структуры не обновляется Когда я добавляю значения в поля динамического массива - PullRequest
1 голос
/ 09 августа 2010

Это связано с моим предыдущим вопросом , и мысль изменит его как отдельный вопрос, поскольку это будет иметь больше смысла.

Я создал свою Структуру как:

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

Без присвоения каких-либо значений, когда я пытаюсь получить размер структуры, он возвращает 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 байта, но мне нужен обновленный размер.

Ответы [ 3 ]

2 голосов
/ 09 августа 2010

Если вы хотите получить размер, как если бы он был неуправляемым типом, вам нужно будет предоставить некоторую информацию о его полях (например, длину массива). Без этого длина массива не была бы учтена.

например.,

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
1 голос
/ 09 августа 2010

Поле Words является массивом, а массивы являются ссылочными типами. Структура на самом деле не содержит элементов массива, она содержит только ссылку на массив, который хранится где-то еще (обычно в куче). Так что SizeOf всегда возвращает один и тот же размер, поскольку размер ссылки не зависит от размера объекта, на который указывает эта ссылка.

0 голосов
/ 09 августа 2010

Marshal.SizeOf() возвращает фиксированный размер класса / структуры.Длина никогда не зависит от содержимого вашего переданного объекта.

Вы можете рассчитать размер с помощью Marshal.SizeOf(typeof(byte))+Marshal.SizeOf(typeof(ushort))*yourarraylength

Другим способом будет использование класса BinaryFormatter для сериализации вашей структурыдвоичная форма.Он возвращает вам байтовый массив.Если вы возьмете его длину, вы знаете его серийный размер.Обратите внимание, что результат BinaryFormatter не может быть легко прочитан языком, отличным от .NET, поскольку его формат является родным только для .net.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...