Pack = 4 and Pack = 1 makes the struct not equivalent to its C declaration

核能气质少年 提交于 2019-12-13 06:00:10

问题


There is struct:

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct WAVEFORMATEX
    {
        public ushort wFormatTag;
        public ushort nChannels;
        public ushort nSamplesPerSec;
        public uint nAvgBytesPerSec;
        public ushort nBlockAlign;
        public ushort wBitsPerSample;
        public ushort cbSize;
    };
    public WAVEFORMATEX audioInfo = new WAVEFORMATEX();

With Pack=4 Marshal.SizeOf(audioInfo) returns 20 bytes

With Pack=1 - Length = 16 bytes.

On C++ level I do not use any options like "Pack" and sizeof is always = 16

But problem happens when I pass ref to the struct from C# to C++ (Interop).

If it's aligned Pack=4 the result looks correct, when Pack=1, then nAvgBytesPerSec comes with too high (abnormal) value, but others are Ok.

So the missing point is why in C++ the value comes ok with natural length of 16 bytes, but in C# the same value (nAvgBytesPerSec) is ok only with Pack=4 when length is 20 bytes, which is obviously longer up to 4 bytes? What happens on Interop level in that case? What (who) takes care of alignment and correct transfer data from C++ to C#?


回答1:


Where did you get your struct layout for WAVEFORMATEX?

From everything I can see online, the correct layout for it is:

typedef struct {
  WORD  wFormatTag;
  WORD  nChannels;
  DWORD nSamplesPerSec;
  DWORD nAvgBytesPerSec;
  WORD  nBlockAlign;
  WORD  wBitsPerSample;
  WORD  cbSize;
} WAVEFORMATEX;

in C/C++, which translates to this in C#:

[StructLayout(LayoutKind.Sequential)]
struct WAVEFORMATEX
{
    public ushort    wFormatTag;
    public ushort    nChannels;
    public uint        nSamplesPerSec;
    public uint        nAvgBytesPerSec;
    public ushort    nBlockAlign;
    public ushort    wBitsPerSample;
    public ushort    cbSize;
}

Can you try marshaling this and see what happens?



来源:https://stackoverflow.com/questions/32263209/pack-4-and-pack-1-makes-the-struct-not-equivalent-to-its-c-declaration

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!