`
ors501ln
  • 浏览: 11992 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

C++Union结构体转换成C#代码

 
阅读更多

C++Union结构体转换成C#代码
2010年10月27日
  有关.net的P/Invoke操作也算了解,但说不上太深,基本的函数调用还可以,但对于一些复杂的数据结构,如上面代码中的联合(union)就无法把其转换为C#以使用的结构。
  注:已经看过《如何在C#中模拟C++的联合(Union)》
  http://www.cnblogs.com/allenlooplee/archive/2004/12/25/81917.html
  此联合是Windows CE中调用RIL接口接收短信时,短信的数据结构
  代码如下,也可以参考MSDN,更清楚:
  MSDN:http://msdn.microsoft.com/en-us/library/aa919458.aspx
  代码:
  C/C++ code typedef struct {  DWORD cbSize;  DWORD dwParams;  RILADDRESS raSvcCtrAddress;  DWORD dwType;  DWORD dwFlags;  UNION {    struct {            RILADDRESS raOrigAddress;            DWORD dwProtocolID;            RILMSGDCS rmdDataCoding;            SYSTEMTIME stSCReceiveTime;            DWORD cbHdrLength;            DWORD cchMsgLength;            BYTE rgbHdr[MAXLENGTH_HDR];            BYTE rgbMsg[MAXLENGTH_MSG];           } msgInDeliver;    struct {            DWORD dwTgtMsgReference;            RILADDRESS raTgtRecipAddress;            SYSTEMTIME stTgtSCReceiveTime;            SYSTEMTIME stTgtDischargeTime;            DWORD dwTgtDlvStatus;            DWORD dwProtocolID;            RILMSGDCS rmdDataCoding;            DWORD cbHdrLength;            DWORD cchMsgLength;            BYTE rgbHdr[MAXLENGTH_HDR];            BYTE rgbMsg[MAXLENGTH_MSG];           } msgInStatus;    struct {            RILADDRESS raDestAddress;            DWORD dwProtocolID;            RILMSGDCS rmdDataCoding;            DWORD dwVPFormat;            SYSTEMTIME stVP;            DWORD cbHdrLength;            DWORD cchMsgLength;            BYTE rgbHdr[MAXLENGTH_HDR];            BYTE rgbMsg[MAXLENGTH_MSG];           } msgOutSubmit;    struct {            DWORD dwProtocolID;            DWORD dwCommandType;            DWORD dwTgtMsgReference;            RILADDRESS raDestAddress;            DWORD cbCmdLength;            BYTE rgbCmd[MAXLENGTH_CMD];           } msgOutCommand;    struct {            DWORD dwGeoScope;            DWORD dwMsgCode;            DWORD dwUpdateNumber;            DWORD dwID;            RILMSGDCS rmdDataCoding;            DWORD dwTotalPages;            DWORD dwPageNumber;            DWORD cchMsgLength;            BYTE rgbMsg[MAXLENGTH_MSG];           } msgBcGeneral;    struct {            DWORD cchMsgLength;            BYTE rgbMsg[MAXLENGTH_MSG];           } msgOutRaw;    struct {            RILADDRESS raOrigAddress;            RILSUBADDRESS rsaOrigSubaddr;            SYSTEMTIME stSCReceiveTime;            SYSTEMTIME stValidityPeriodAbs;            SYSTEMTIME stValidityPeriodRel;            SYSTEMTIME stDeferredDelTimeAbs;            SYSTEMTIME stDeferredDelTimeRel;            DWORD dwNumMsgs;            RILADDRESS raCallBackNumber;             DWORD dwMsgPriority;             DWORD dwMsgPrivacy;            BOOL bUserAckRequest;             DWORD dwMsgDisplayMode;            DWORD dwTeleservice;             DWORD dwMsgID;            DWORD dwMsgLang;            DWORD dwMsgEncoding;            DWORD cchMsgLength;            BYTE rgbMsg[MAXLENGTH_MSG];           } msgIS637InDeliver;    struct {            RILADDRESS raDestAddress;            RILSUBADDRESS rsaDestSubaddr;            BOOL bDigit;            SYSTEMTIME stValidityPeriodAbs;            SYSTEMTIME stValidityPeriodRel;            SYSTEMTIME stDeferredDelTimeAbs;            SYSTEMTIME stDeferredDelTimeRel;            BOOL bDeliveryAckRequest;            BOOL bUserAckRequest;            BOOL bBearerReplyRequest;            DWORD dwReplySeqNumber;            DWORD dwMsgDisplayMode;            RILADDRESS raCallBackNumber;            DWORD dwMsgPriority;            DWORD dwMsgPrivacy;            DWORD dwTeleservice;            DWORD dwMsgID;            DWORD dwMsgLang;            DWORD dwMsgEncoding;             DWORD cchMsgLength;              BYTE rgbMsg[MAXLENGTH_MSG];            } msgIS637OutSubmit;    struct {             RILADDRESS raOrigAddress;            RILSUBADDRESS rsaOrigSubaddr;            SYSTEMTIME stSCReceiveTime;            DWORD dwCauseCode;            DWORD dwReplySeqNumber;            DWORD dwUserResponseCode;            DWORD dwMsgStatusType;            DWORD dwMsgID;            DWORD dwMsgLang;            DWORD dwMsgEncoding;            DWORD cchMsgLength;            BYTE rgbMsg[MAXLENGTH_MSG];           } msgIS637InStatus;    struct {            RILADDRESS raDestAddress;            RILSUBADDRESS rsaDestSubaddr;            BOOL bDigit;            DWORD dwReplySeqNumber;            DWORD dwUserResponseCode;            DWORD dwMsgID;            DWORD dwMsgLang;            DWORD dwMsgEncoding;            DWORD cchMsgLength;            BYTE rgbMsg[MAXLENGTH_MSG];           } msgIS637OutStatus;        }} RILMESSAGE;
  下面的代码是实现:
  C# code     #region RILMESSAGE struct    public struct RILMESSAGE    {        public UInt32 cbSize;        public UInt32 dwParams;        [MarshalAs(UnmanagedType.Struct, SizeConst = 528)]        public RILADDRESS raSvcCtrAddress;        public UInt32 dwType;        public UInt32 dwFlags;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1356)] //最大的结构为2212。短信结构长度为1356        public byte[] Msg;    }    #region 用于UNION中的10个Struct    [StructLayout(LayoutKind.Sequential)]    public struct msgInDeliver    {        public RILADDRESS raOrigAddress;        public UInt32 dwProtocolID;        public RILMSGDCS rmdDataCoding;        public SYSTEMTIME stSCReceiveTime;        public UInt32 cbHdrLength;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]        public byte[] rgbHdr;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgInStatus    {        public UInt32 dwTgtMsgReference;        public RILADDRESS raTgtRecipAddress;        public SYSTEMTIME stTgtSCReceiveTime;        public SYSTEMTIME stTgtDischargeTime;        public UInt32 dwTgtDlvStatus;        public UInt32 dwProtocolID;        public RILMSGDCS rmdDataCoding;        public UInt32 cbHdrLength;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]        public byte[] rgbHdr;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgOutSubmit    {        public RILADDRESS raDestAddress;        public UInt32 dwProtocolID;        public RILMSGDCS rmdDataCoding;        public UInt32 dwVPFormat;        public SYSTEMTIME stVP;        public UInt32 cbHdrLength;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]        public byte[] rgbHdr;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgOutCommand    {        public UInt32 dwProtocolID;        public UInt32 dwCommandType;        public UInt32 dwTgtMsgReference;        public RILADDRESS raDestAddress;        public UInt32 cbCmdLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]        public byte[] rgbCmd;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgBcGeneral    {        public UInt32 dwGeoScope;        public UInt32 dwMsgCode;        public UInt32 dwUpdateNumber;        public UInt32 dwID;        public RILMSGDCS rmdDataCoding;        public UInt32 dwTotalPages;        public UInt32 dwPageNumber;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgOutRaw    {        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgIS637InDeliver    {        public RILADDRESS raOrigAddress;        public RILSUBADDRESS rsaOrigSubaddr;        public SYSTEMTIME stSCReceiveTime;        public SYSTEMTIME stValidityPeriodAbs;        public SYSTEMTIME stValidityPeriodRel;        public SYSTEMTIME stDeferredDelTimeAbs;        public SYSTEMTIME stDeferredDelTimeRel;        public UInt32 dwNumMsgs;        public RILADDRESS raCallBackNumber;        public UInt32 dwMsgPriority;        public UInt32 dwMsgPrivacy;        public bool bUserAckRequest;        public UInt32 dwMsgDisplayMode;        public UInt32 dwTeleservice;        public UInt32 dwMsgID;        public UInt32 dwMsgLang;        public UInt32 dwMsgEncoding;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgIS637OutSubmit    {        public RILADDRESS raDestAddress;        public RILSUBADDRESS rsaDestSubaddr;        private bool bDigit;        public SYSTEMTIME stValidityPeriodAbs;        public SYSTEMTIME stValidityPeriodRel;        public SYSTEMTIME stDeferredDelTimeAbs;        public SYSTEMTIME stDeferredDelTimeRel;        private bool bDeliveryAckRequest;        private bool bUserAckRequest;        private bool bBearerReplyRequest;        public UInt32 dwReplySeqNumber;        public UInt32 dwMsgDisplayMode;        public RILADDRESS raCallBackNumber;        public UInt32 dwMsgPriority;        public UInt32 dwMsgPrivacy;        public UInt32 dwTeleservice;        public UInt32 dwMsgID;        public UInt32 dwMsgLang;        public UInt32 dwMsgEncoding;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgIS637InStatus    {        public RILADDRESS raOrigAddress;        public RILSUBADDRESS rsaOrigSubaddr;        public SYSTEMTIME stSCReceiveTime;        public UInt32 dwCauseCode;        public UInt32 dwReplySeqNumber;        public UInt32 dwUserResponseCode;        public UInt32 dwMsgStatusType;        public UInt32 dwMsgID;        public UInt32 dwMsgLang;        public UInt32 dwMsgEncoding;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    [StructLayout(LayoutKind.Sequential)]    public struct msgIS637OutStatus    {        public RILADDRESS raDestAddress;        public RILSUBADDRESS rsaDestSubaddr;        public bool bDigit;        public UInt32 dwReplySeqNumber;        public UInt32 dwUserResponseCode;                public UInt32 dwMsgID;        public UInt32 dwMsgLang;        public UInt32 dwMsgEncoding;        public UInt32 cchMsgLength;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]        public byte[] rgbMsg;    }    #endregion    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]    public struct RILSUBADDRESS    {        public UInt32 cbSize;        public UInt32 dwParams;        public UInt32 dwType;        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]        public string wszSubAddress;    }    [StructLayout(LayoutKind.Sequential)]    public struct RILMSGDCS    {        public UInt32 cbSize;        public UInt32 dwParams;        public UInt32 dwType;        public UInt32 dwFlags;        public UInt32 dwMsgClass;        public UInt32 dwAlphabet;        public UInt32 dwIndication;        public UInt32 dwLanguage;    }    [StructLayout(LayoutKind.Sequential)]    public struct SYSTEMTIME    {        public ushort wYear;        public ushort wMonth;        public ushort wDayOfWeek;        public ushort wDay;        public ushort wHour;        public ushort wMinute;        public ushort wSecond;        public ushort wMilliseconds;        public override string ToString()        {            return wYear.ToString() + "-" + wMonth.ToString() + "-" + wDay.ToString() + " "                   + wHour.ToString() + ":" + wMinute.ToString() + ":" + wSecond.ToString();        }    }    #endregion
  具体调用的时候,因为同一时间联合中只有一个结构,而且可以根据dwType来确认是使用的哪一个结构,这时可以使用如下的方法,把byte[]转换成相应的结构:
  lpData是IntPtr类型
  C# code RILMESSAGE msg = (RILMESSAGE) Marshal.PtrToStructure(lpData, typeof (RILMESSAGE));
  以上取出了RILMESSAGE
  C# code         msgInDeliver msgIn = (msgInDeliver)Ril.BytesToStruct(msg.Msg, typeof(msgInDeliver));        public static object BytesToStruct(byte[] bytes, Type type)        {            //得到结构的大小            int size = Marshal.SizeOf(type);            //byte数组长度小于结构的大小            if (size > bytes.Length)            {                //返回空                return null;            }            //分配结构大小的内存空间            IntPtr structPtr = Marshal.AllocHGlobal(size);            //将byte数组拷到分配好的内存空间            Marshal.Copy(bytes, 0, structPtr, size);            //将内存空间转换为目标结构            object obj = Marshal.PtrToStructure(structPtr, type);            //释放内存空间            Marshal.FreeHGlobal(structPtr);            //返回结构            return obj;        }
  以上把byte[]类型的msg.Msg转换为结构msgInDeliver。msg.Msg也就是联合指向的内存中的数据
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics