Marshalling char arrays in Struct for windows CE
How would one marshal the char arrays in the following struct definition? in the .Net CompactFramework (For Windows CE)
//Struct of request for transaction
typedef struct _VXN_REQUEST
{
char DID [33];
char MID [33];
char TID [33];
char ClientRef [33];
char Payload [8192];
ULONG PayloadLength;
} VXN_REQUEST, *LPVXN_REQUEST;
I tried to Marshal it like this but it doesn't seem to work
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct VXN_REQUEST
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string DID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string MID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string TID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string ClientRef;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string Payload;
public uint PayloadLength;开发者_高级运维
}
Also Tried like This but none of them works, the native code is taking it as a single char instead.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct VXN_REQUEST
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 33)]
public char[] DID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 33)]
public char[] MID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 33)]
public char[] TID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 33)]
public char[] ClientRef;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 33)]
public char[] Payload;
public uint PayloadLength;
}
A .NET char takes two bytes, it stores a Unicode codepoint encoded in utf-16. Use byte instead of char in the declaration. Use Encoding.ASCII.GetBytes() to fill the byte[] if you actually need these fields to be strings.
Change your P/Invoke declaration to take in a byte[] instead of the struct, then define it like this:
public class VXN_REQUEST
{
private byte[] m_data;
public const int Size = 8328;
public VXN_REQUEST()
{
m_data = new byte[Size];
}
public static implicit operator byte[](VXN_REQUEST req)
{
return req.m_data;
}
public string DID
{
get { return Encoding.ASCII.GetString(m_data, 0, 33).Trim('\0'); }
set
{
// TODO: verify that 'value' isn't too long
// first clear the contents
var empty = new byte[33];
Buffer.BlockCopy(empty, 0, m_data, 0, empty.Length);
// copy data
Encoding.ASCII.GetBytes(value).CopyTo(m_data, 0);
}
}
public string MID
{
get { return Encoding.ASCII.GetString(m_data, 33, 33).Trim('\0'); }
}
public string TID
{
get { return Encoding.ASCII.GetString(m_data, 66, 33).Trim('\0'); }
}
public string ClientRef
{
get { return Encoding.ASCII.GetString(m_data, 99, 33).Trim('\0'); }
}
public string Payload
{
get { return Encoding.ASCII.GetString(m_data, 132, PayloadLength).Trim('\0'); }
}
public int PayloadLength
{
get { return BitConverter.ToInt32(m_data, 8324); }
}
}
And for the record, 33-charater lengths seems really odd to me.
精彩评论