Как преобразовать структуру C ++ в эквивалент C #? - PullRequest
0 голосов
/ 02 мая 2018

Это моя структура C ++ (в документах говорится, что каждый экземпляр должен иметь размер ровно 10 байт):

#pragma pack (1)
struct LaserPoint {
    WORD x;
    WORD y;
    byte colors[6];
};

Я сделал следующую структуру C #:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;                   // 2 bytes
    public UInt16 y;                   // 2 bytes
    public byte[] colors;              // 6 bytes
}

Вот мой полный тестовый код в моем проекте на C #:

using System;
using System.Runtime.InteropServices;

namespace StructSizeTest {
    class Program {

        [StructLayout(LayoutKind.Sequential, Pack=1)]
        public struct LaserPoint {
            public UInt16 x;                   // 2 bytes
            public UInt16 y;                   // 2 bytes
            public byte[] colors;              // byte[6] = 6 bytes
        }

        static void Main(string[] args) {

            LaserPoint point = new LaserPoint();
            point.x = (UInt16)16384;
            point.y = (UInt16)32768;
            point.colors = new byte[6];
            point.colors[0] = 255;
            point.colors[1] = 255;
            point.colors[2] = 255;
            point.colors[3] = 255;
            point.colors[4] = 255;
            point.colors[5] = 255;

            Console.WriteLine("LaserPoint.Size: " + Marshal.SizeOf(point));

            Console.ReadLine();
        }

    }
}

Это вывод на консоль:

LaserPoint.Size: 8

Почему размер point 8 байт, а не 10 байт?

UInt16  = 2 bytes
UInt16  = 2 bytes
byte[6] = 6 bytes
Total   = 10 bytes ?

Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;                   // 2 bytes
    public UInt16 y;                   // 2 bytes
    public byte[] colors;              // 6 bytes
}

byte[] colors не имеет ширину 6 байт. Это даже не фактический массив, а ссылка на байтовый массив в куче. В зависимости от вашей платформы, он имеет размер 32 бита (4 байта) или 64 бита (8 байт) (внутренне это указатель). Вот почему в результате вы получаете размер 8 байт (2 байта + 2 байта + 4 байта). На 64-битной платформе вы получите размер 12 байт (2 + 2 + 8).

Чтобы struct вел себя как C ++ struct, добавьте MarshalAsAttribute и укажите UnmanagedType.ByValArray и SizeConst:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;                  
    public UInt16 y;                         
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] colors;             
}
0 голосов
/ 02 мая 2018

Я думаю, что проблема с массивом ... Попробуйте это:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;                   // 2 bytes
    public UInt16 y;                   // 2 bytes
    [MarhalAs(UnmanagedType.ByValArray, SizeConst = 6]
    public byte[] colors;              // 6 bytes
}
...