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也就是联合指向的内存中的数据
发表评论
-
CQ与其他聊天工具继承
2012-01-20 01:40 554CQ与其他聊天工具继承 2010年06月13日 VBSc ... -
隐藏命令行CMD框
2012-01-20 01:39 822隐藏命令行CMD框 2010年07月18日 vbs脚本: ... -
insert->Step Generator
2012-01-20 01:39 490insert->Step Generator 2010 ... -
[转]使用C#开发ActiveX控件全攻略
2012-01-20 01:39 762[转]使用C#开发ActiveX控 ... -
程式交易(一)大智慧函数(下)
2012-01-19 09:29 849程式交易(一)大智慧函数(下) 2011年07月24日 ... -
关于图像格式
2012-01-19 09:29 797关于图像格式 2010年06 ... -
.net如何上传图片,并生成缩略图效果
2012-01-19 09:29 748.net如何上传图片,并生成缩略图效果 2011年04月18 ... -
学Photoshop前的19句经典忠告
2012-01-19 09:29 857学Photoshop前的19句经典 ... -
安全bios手册(5)
2012-01-19 09:29 554安全bios手册(5) 2010年06月20日 ... -
指针与引用的一角
2012-01-17 02:04 723指针与引用的一角 2011 ... -
【转】Android 的cpu 硬盘 内存 网络设置 系统信息 硬件信息
2012-01-17 02:04 602【转】Android 的cpu 硬盘 ... -
MD5算法实现注意点
2012-01-17 02:04 659MD5算法实现注意点 2011年03月02日 最近很有危 ... -
日语词汇
2012-01-15 21:25 395日语词汇 2010年11月24日 时间变化:推移:すいい ... -
1级能力考试知识汇总
2012-01-15 21:25 6091级能力考试知识汇总 2009年06月04日 人物题包括 ... -
小儿时,我这样被剃头
2012-01-15 21:25 332小儿时,我这样被剃头 2 ... -
化村姑为女郎
2012-01-15 21:25 528化村姑为女郎 2009年07 ...
相关推荐
在写C#TCP通信程序时,发送数据时,只能发送byte数组,处理起来比较麻烦不说,如果是和c++等写的程序通信的话,很多的都是传送结构体,在VC6.0中可以很方便的把一个char[]数组转换为一个结构体,而在C#却不能直接把...
把c++的结构体、数据类型、函数定义转换成对应的c#表达,很强大。
资源代码演示的是c#代码调用c++ DLL 的方式。该演示为原创,绝非搬砖。解决了c# 调用 C++ Dll获取相关信息之如何传递结构体数组引用以及如何处理获取到的结构体数组数据的问题。
因项目需要,要用C#程序调用C++的一个DLL库,了解到有个工具叫CLRInsideOut,其中一个的功能就是把C++下的结构体或者函数声明转换成C#下的定义,自动生成 C# 代码。 现上传上来,方便大家编码,给有需要的人,个人...
C# 与 C++ 数据类型比较及结构体转换 C# 与 C++ 数据类型比较及结构体转换
C#实现结构体与数组间的转换,包括:同时支持大小端;支持自定义数据类型;支持数组类型结构体成员,带单元测试
网络通信中C、C++结构体转C#结构体
c#调用C++动态库、执行回调函数,并回传结构体参数数据。vs2017环境编写C#和C++动态库,这个为完整工程例子,可供相关人员学习参考。
C#调用C++生成的DLL,并返回结构体引用或者结构体指针多个值,工程已编译好
用于在C++结构体和json/xml之间互相转换, bson在xbson中支持。 只需要头文件, 无需编译库文件。 具体可以参考example的例子
下面小编就为大家分享一篇基于C#调用c++Dll结构体数组指针的问题详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
c++调用C# COM 参数是结构体数组
在写C#TCP通信程序时,发送数据时,只能发送byte数组,处理起来比较麻烦不说,如果是和VC6.0等写的程序通信的话,很多的都是传送结构体,在VC6.0中可以很方便的把一个char[]数组转换为一个结构体,而在C#却不能直接...
主要解决开发人员遇到的常规问题,针对 C# 结构体 和 Byte 数组之间互相转换遇到的问题,代码中进行了简单封装,方便客户调用,下载可以直接使用,方便快捷。
主要介绍了C#调用C++DLL传递结构体数组的终极解决方案的相关资料,需要的朋友可以参考下
C++中自定义结构体选择一个键值 调用sort qsort排序
C#遍历结构体
c、c++如果在日志中查看某个结构字段信息,只能通过printf逐个格式化,工作量大; 该dll库通知pdb文件分析结构体字段位置,并根据类型格式一个完整字符串,极大降低了开发者工作量。 1、可通过cdump\Release\...
C#调用C++封装成DLL的结构体及类库, 使用数据结构类型, 使用动态库调用方式,函数入参为结构体,返回参数为结构体,使用out,ref 传统参数