有关.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
结构代码:
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;
结构中使用到的其它结构,MSDN中都有,可以参考
http://msdn.microsoft.com/en-us/library/aa919130(v=MSDN.10).aspx
我自己写的C#的封装,但运行出错。
代码:
private struct RILMESSAGE
{
public UInt32 cbSize; // @field structure size in bytes
public UInt32 dwParams; // @field indicates valid parameters
public RILADDRESS raSvcCtrAddress;
public UInt32 dwType;
public UInt32 dwFlags;
public UNION Msg;
}
[StructLayout(LayoutKind.Explicit)]
private struct UNION
{
[FieldOffset(0)]
public msgInDeliver _msgInDeliver;
[FieldOffset(0)]
public msgInStatus _msgInStatus;
[FieldOffset(0)]
public msgOutSubmit _msgOutSubmit;
[FieldOffset(0)]
public msgOutCommand _msgOutCommand;
[FieldOffset(0)]
public msgBcGeneral _msgBcGeneral;
[FieldOffset(0)]
public msgOutRaw _msgOutRaw;
}
#region 用于UNION中的10个Struct
[StructLayout(LayoutKind.Sequential)]
private 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)]
private 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)]
private 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)]
private 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)]
private 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)]
private struct msgOutRaw
{
public UInt32 cchMsgLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] rgbMsg;
}
#endregion
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
private struct RILADDRESS
{
public UInt32 cbSize; // @field structure size in bytes
public UInt32 dwParams; // @field indicates valid parameters
public UInt32 dwType;
public UInt32 dwNumPlan;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public StringBuilder wszAddress;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct RILSUBADDRESS
{
public UInt32 cbSize; // @field structure size in bytes
public UInt32 dwParams; // @field indicates valid parameters
public UInt32 dwType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public StringBuilder wszSubAddress;
}
[StructLayout(LayoutKind.Sequential)]
private struct RILMSGDCS
{
public UInt32 cbSize; // @field structure size in bytes
public UInt32 dwParams; // @field indicates valid parameters
public UInt32 dwType;
public UInt32 dwFlags;
public UInt32 dwMsgClass;
public UInt32 dwAlphabet;
public UInt32 dwIndication;
public UInt32 dwLanguage;
}
[StructLayout(LayoutKind.Sequential)]
private struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
#endregion
有对C#互操作有经验的前辈给于指点,如能帮助实现,不胜感激。
C#测试程序源代码:
测试程序说明:
环境:vs2005 + Windows Mobile 5.0 SDK
功能说明:当手机收到短信时,截获短信。
当手机收到短信时,代码中的RIL类中的_NotifyCallback函数会执行,并可以用以下代码取出消息体。
RILMESSAGE msg = (RILMESSAGE)Marshal.PtrToStructure(lpData, typeof(RILMESSAGE));
但因为RILMESSAGE结构到c#的模拟失败,所以程序报错。