我有一个库,我想为它编写一个.NET包装器。目前,我正在使用P / Invoke,但由于我没有库的源代码或大量的C知识,因此我在编组方面遇到了困难。它到目前为止(有点),但感觉就像一个黑客。
C签名
typedef struct
{
unsigned short sAddress[MAX_ADDRESS_CHAR_LENGTH + 1];
unsigned short sCallback[MAX_CALLBACK_CHAR_LENGTH + 1];
unsigned short sMessage[(MAX_MESSAGE_CHAR_LENGTH + 1) ];
unsigned short sSmscAddress[MAX_ADDRESS_CHAR_LENGTH+1];
unsigned short sSubject[MAX_SUBJECT_CHAR_LENGTH + 1];
unsigned char msgLength;
unsigned char pduType;
unsigned short msgRef;
unsigned char msgSequence;
unsigned char msgTotal;
EMsgPriority nPriority;
struct tm tTime;
EncodingType encoding;
unsigned char bReceipt;
unsigned long dwDataMask;
struct tm tValidity;
unsigned char nValidityType;
unsigned char bRelativeValidityFlag;
unsigned char isDeliveryAck;
} SMS_MSG_DATA;
unsigned short SmsEncodeMessage( SMS_MSG_DATA* sms_msg, unsigned char* msg_buf,
unsigned short* msg_buf_len );
C#P / Invoke
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SMS_MSG_DATA {
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=SmsEncoding.MAX_ADDRESS_CHAR_LENGTH+1)]
public string sAddress;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=SmsEncoding.MAX_CALLBACK_CHAR_LENGTH+1)]
public string sCallback;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=SmsEncoding.MAX_MESSAGE_CHAR_LENGTH+1)]
public string sMessage;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=SmsEncoding.MAX_ADDRESS_CHAR_LENGTH+1)]
public string sSmscAddress;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=SmsEncoding.MAX_SUBJECT_CHAR_LENGTH+1)]
public string sSubject;
public byte msgLength;
public byte pduType;
public ushort msgRef;
public byte msgSequence;
public byte msgTotal;
public EMsgPriority nPriority;
public tm tTime;
public EncodingType encoding;
public byte bReceipt;
public long dwDataMask;
public tm tValidity;
public byte nValidityType;
public byte bRelativeValidityFlag;
public byte isDeliveryAck;
}
[DllImport(Constants.LIB_SMSENCODE)]
public static extern ErrorCode SmsEncodeMessage(ref SMS_MSG_DATA sms_msg,
byte[] msg_buf, ref short msg_buf_len);
本质上,它的作用是采用SMS_MSG_DATA
结构并将其输出为msg_buf
字节数组中的二进制格式。 msg_buf_len
的初始值是字节数组的大小,但是当编码完成时,它被设置为实际填充的字节数。
C ++ / CLI包装器如何使这个过程更容易和更清洁?
答案 0 :(得分:1)
这是完全合理的P / Invoke代码,尽管你应该确保你不传递Unicode(检查你的结构定义。),因为你的所有本机声明似乎都采用ANSI字符串。
C ++ / CLI在这里并没有真正帮助你 - 它让你的生活更轻松的地方是当你想要编写一些本机代码块,并使C#部分的接口更简单。你在这里唯一可以做的就是如果在C#方面你真的只关心1-2个参数,你可以让C ++ / CLI DLL为你填写其余部分而不用担心C#端的丑陋代码
答案 1 :(得分:0)
C ++ / CLI可以使这更容易,因为您不必编写PInvoke定义。相反,您可以直接使用原始的本地SMS_MSG_DATA
结构。您可以自由编写一个更好看的包装器结构,该结构在内部转换为SMS_MSG_DATA
。这个包装器结构不需要任何丑陋的PInvoke声明,并且可以更加符合托管指南。