如何以 32/64 位兼容方式在 C# 中定义 MAPINAMEID 结构?

How to define MAPINAMEID structure in C# in 32/64-bit compatible way?

在 C 中,MAPINAMEID 定义为:

typedef struct _MAPINAMEID
{
    LPGUID lpguid;
    ULONG ulKind;
    union {
        LONG lID;
        LPWSTR lpwstrName;
    } Kind;

} MAPINAMEID, FAR * LPMAPINAMEID;

在C#中,我的定义是:

    [StructLayout(LayoutKind.Explicit)]
    private struct MAPINAMEID
    {
        [FieldOffset(0)]
        public IntPtr lpguid;
        [FieldOffset(8)]
        public uint ulKind;
        [FieldOffset(16)]
        public int lID;
        [FieldOffset(16)]
        public IntPtr lpwstrName;
    };

显然,它只能在 64 位模式下工作,对于 32 位模式我需要不同的偏移值。不幸的是,FieldOffset 属性不允许使用可计算值(如 IntPtr.Size)。是否有一种独立于平台的方式来指定偏移量(或者以其他方式告诉编译器我希望 lID 和 lpwstrName 共享相同的偏移量?

你可以这样声明:

[StructLayout(LayoutKind.Sequential)]
private struct MAPINAMEID
{
    public IntPtr lpguid;
    public uint ulKind;
    public IntPtr lpwstrName; // or lID
};

并在需要时使用 IntPtr 32 位转换在 lpwstrName 和 lId 之间切换(LONG 和 ULONG 是 32 位的)。