帮忙将一个C++的结构体转化为C#的结构体(union)

nm_wyh 2018-04-23 10:59:45
typedef struct _devicemodeW {
WCHAR dmDeviceName[CCHDEVICENAME];
WORD dmSpecVersion;
WORD dmDriverVersion;
WORD dmSize;
WORD dmDriverExtra;
DWORD dmFields;
union {
/* printer only fields */
struct {
short dmOrientation;
short dmPaperSize;
short dmPaperLength;
short dmPaperWidth;
short dmScale;
short dmCopies;
short dmDefaultSource;
short dmPrintQuality;
};
/* display only fields */
struct {
POINTL dmPosition;
DWORD dmDisplayOrientation;
DWORD dmDisplayFixedOutput;
};
};
short dmColor;
short dmDuplex;
short dmYResolution;
short dmTTOption;
short dmCollate;
WCHAR dmFormName[CCHFORMNAME];
WORD dmLogPixels;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
union {
DWORD dmDisplayFlags;
DWORD dmNup;
};
DWORD dmDisplayFrequency;
#if(WINVER >= 0x0400)
DWORD dmICMMethod;
DWORD dmICMIntent;
DWORD dmMediaType;
DWORD dmDitherType;
DWORD dmReserved1;
DWORD dmReserved2;
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= _WIN32_WINNT_NT4)
DWORD dmPanningWidth;
DWORD dmPanningHeight;
#endif
#endif /* WINVER >= 0x0400 */
} DEVMODEW, *PDEVMODEW, *NPDEVMODEW, *LPDEVMODEW;
...全文
737 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
nm_wyh 2018-04-26
  • 打赏
  • 举报
回复
引用 2 楼 bloodish 的回复:

[StructLayout(LayoutKind.Sequential)]
    public struct PrinterFields
    {
        public short dmOrientation;
        //more
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DisplayFields
    {
        //POINTL dmPosition;
        public uint dmDisplayOrientation;
        //more...
    }
   
    [StructLayout(LayoutKind.Explicit)]
    public struct DEVMODEW
    {
        //replace 128 with real string size
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
        [FieldOffset(0)]
        public string dmDeviceName;
        [FieldOffset(128)]
        public short dmSpecVersion;
        //define other fields with offset by yourself
        //begin union, assumes union field offset starts from 136
        [FieldOffset(136)]
        public PrinterFields printerFields;
        [FieldOffset(136)]
        public PrinterFields displayFields;
        //end union
        //assumes remain fields' offset start from 154
        [FieldOffset(154)]
        public short dmColor;
        //more...
    }
包含union的struct如果要转成托管代码对应的struct,需要显示指定struct layout为explict,且显示标明field offset。 union中包含的各个成员的field offset设为相同。 BTW:原则上能用C++/CLI二次封装就别用PInvoke
谢谢,最后也没用这个方法转,但这个方法应该是正确的,我最后把这个玩意用C++又封装了一遍,把不友好的结构体都封装成了dll,最后也解决了这个问题。
bloodish 2018-04-24
  • 打赏
  • 举报
回复

[StructLayout(LayoutKind.Sequential)]
    public struct PrinterFields
    {
        public short dmOrientation;
        //more
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DisplayFields
    {
        //POINTL dmPosition;
        public uint dmDisplayOrientation;
        //more...
    }
   
    [StructLayout(LayoutKind.Explicit)]
    public struct DEVMODEW
    {
        //replace 128 with real string size
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
        [FieldOffset(0)]
        public string dmDeviceName;
        [FieldOffset(128)]
        public short dmSpecVersion;
        //define other fields with offset by yourself
        //begin union, assumes union field offset starts from 136
        [FieldOffset(136)]
        public PrinterFields printerFields;
        [FieldOffset(136)]
        public PrinterFields displayFields;
        //end union
        //assumes remain fields' offset start from 154
        [FieldOffset(154)]
        public short dmColor;
        //more...
    }
包含union的struct如果要转成托管代码对应的struct,需要显示指定struct layout为explict,且显示标明field offset。 union中包含的各个成员的field offset设为相同。 BTW:原则上能用C++/CLI二次封装就别用PInvoke
nm_wyh 2018-04-23
  • 打赏
  • 举报
回复
WinGDI.h中的一个结构体,简直是坑爹。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧