Pack = 4和Pack = 1使得结构体不等同于它的C声明

本文关键字:Pack 等同于 声明 结构体 | 更新日期: 2023-09-27 18:10:14

有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)返回20字节

With Pack=1 - Length = 16 bytes.

在c++级别,我不使用任何选项,如"Pack"和sizeof总是= 16

但是当我将ref从c#传递到c++(互操作)时,问题发生了。

如果它对齐Pack=4,结果看起来是正确的,当Pack=1时,那么nAvgBytesPerSec的值太高(异常),但其他都是Ok的。

所以缺失的点是为什么在c++中值来ok的自然长度为16个字节,但在c#中相同的值(nAvgBytesPerSec)是ok的,只有当长度为20个字节时,Pack=4,这显然更长至4个字节?在这种情况下,互操作层面会发生什么?什么(谁)负责从c++到c#的对齐和正确传输数据?

Pack = 4和Pack = 1使得结构体不等同于它的C声明

你从哪里得到WAVEFORMATEX的结构布局?

从我在网上看到的所有内容来看,正确的布局是:

typedef struct {
  WORD  wFormatTag;
  WORD  nChannels;
  DWORD nSamplesPerSec;
  DWORD nAvgBytesPerSec;
  WORD  nBlockAlign;
  WORD  wBitsPerSample;
  WORD  cbSize;
} WAVEFORMATEX;
C/c++中的

,在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;
}

你能试着封送这个,看看会发生什么吗?