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

时间:2018-04-03 13:28:13

标签: c# interop pinvoke

在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共享相同的偏移量?

1 个答案:

答案 0 :(得分:1)

您可以这样声明:

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

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