[英]What does 'aligned' mean, for structs in c?
我正在努力在ac api和.net應用程序之間編寫一些粘合代碼。 為了編寫C#結構,我需要弄清楚這里c端實際發生了什么。
typedef struct CommonDialogBaseParam {
size_t size;
uint8_t reserved[36];
uint32_t magic;
} CommonDialogBaseParam __attribute__ ((__aligned__(8)));
// Somewhere else
#define __attribute__(x)
我很想編寫等效的C#,如下所示:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CommonDialogBaseParam {
public ulong size;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=36)]
public string reserved;
public uint magic;
}
不用說...我真的不需要C#端對“保留”或“魔術”的正確訪問,但是我需要適當地保留成員。
這是一個GCC屬性,用於指定結構的最小對齊方式為8個字節。 可以在以下位置找到該文檔: https : //gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#Common-Type-Attributes
這會影響這些結構的分配,但不會影響結構本身的偏移量。 但是,這確實意味着本地結構在最終成員之后可能會有額外的填充。
C#中沒有與此等效的方法,並且根據本機代碼對結構所做的操作,您可能會遇到問題。 如果由您的C#代碼分配,則結構可能未對齊,但這只會影響性能而不是正確性。 如果本機代碼復制了該結構,則它將嘗試讀取該結構末尾的任何填充。 可以想象這可能導致訪問沖突。 我的猜測是p / invoke使用的堆分配器將以塊大小至少為8的塊形式分配內存,因此您可能會避免這樣做。 但是我懷疑您是否可以依靠它。
拋開這些填充,我將像這樣翻譯您的結構:
[StructLayout(LayoutKind.Sequential)]
public struct CommonDialogBaseParam {
public UIntPtr size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=36)]
public byte[] reserved;
public uint magic;
}
請注意,我已將size_t
映射到UIntPtr
,即無符號指針大小的值。 我個人更希望看到reserved
字段的byte[]
。 據我所知,這對C代碼更真實。
如果要確保結構足夠大,則可以在末尾添加一個額外的字段:
[StructLayout(LayoutKind.Sequential)]
public struct CommonDialogBaseParam {
public UIntPtr size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=36)]
public byte[] reserved;
public uint magic;
private uint padding;
}
由於此結構中包含的所有類型都不具有大於8的大小,因此您可以濫用StructLayout
的Pack
選項來實現所需的效果:
[StructLayout(LayoutKind.Sequential, Pack=8)]
public struct CommonDialogBaseParam {
public UIntPtr size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=36)]
public byte[] reserved;
public uint magic;
}
但是要小心。 本機代碼將結構對齊。 上面的C#聲明將結構對齊,並指定其成員的對齊方式。 碰巧在這里不會影響成員對齊,但並非總是如此。
總而言之,有點不滿意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.