I have a little piece of a library that I would like to write a .NET wrapper for. At the moment, I'm using P/Invoke, but since I don't have the library's source code or a whole lot of C knowledge, I'm having a difficult time with marshaling. It works so far (sort of), but it feels like a hack.
C Signatures
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);
Essentially, what this does is takes the SMS_MSG_DATA
struct and outputs it to a binary format in the msg_buf
byte array. The initial value of msg_buf_len
is the size of the byte array, but when the encoding completes, it is set to the number of bytes actually filled.
How can a C++/CLI wrapper make this process any easier and cleaner?