开发者

Marshalling char arrays in Struct for windows CE

开发者 https://www.devze.com 2023-02-18 10:28 出处:网络
How would one marshal the char arrays in the following struct definition? in the .Net CompactFramework (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.

0

精彩评论

暂无评论...
验证码 换一张
取 消