问题
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