一个编组C#结构 [英] Marshalling a C# structure

查看:416
本文介绍了一个编组C#结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想序列化下面的C#结构:

I am trying to serialize the following c# structure:

[Serializable]
[StructLayout(LayoutKind.Sequential, Size = 70, CharSet = CharSet.Ansi)]
public struct USSDContinueModel
{
    [MarshalAs(UnmanagedType.U4)]
    public uint Command_Length;

    [MarshalAs(UnmanagedType.U4)]
    public uint Command_ID;

    [MarshalAs(UnmanagedType.U4)]
    public uint Command_Status;

    [MarshalAs(UnmanagedType.U4)]
    public uint Sender_ID;

    [MarshalAs(UnmanagedType.U4)]
    public uint Receiver_ID;

    [MarshalAs(UnmanagedType.U1)]
    public uint Ussd_Version;

    [MarshalAs(UnmanagedType.U1)]
    public uint Ussd_Op_Type;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
    public string MsIsdn;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
    public string Service_Code;

    [MarshalAs(UnmanagedType.U1)]
    public uint Code_Scheme;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 182)]
    public string Ussd_Content;

    // Calling this method will return a byte array with the contents
    // of the struct ready to be sent via the tcp socket.
    public byte[] Serialize()
    {
        // allocate a byte array for the struct data
        var buffer = new byte[Marshal.SizeOf(typeof(USSDContinueModel))];

        // Allocate a GCHandle and get the array pointer
        var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        var pBuffer = gch.AddrOfPinnedObject();

        // copy data from struct to array and unpin the gc pointer
        Marshal.StructureToPtr(this, pBuffer, false);
        gch.Free();

        return buffer;
    }

    // this method will deserialize a byte array into the struct.
    public void Deserialize(ref byte[] data)
    {
        var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
        this = (USSDContinueModel)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(USSDContinueModel));
        gch.Free();
    }
}

当我尝试序列结构的一个实例说

when i try to serialize an instance of the structure say:

        public USSDContinueModel continueModel;
        continueModel.Command_Length = 174;
        continueModel.Command_ID = 0x00000070;
        continueModel.Command_Status = 0;
        continueModel.Sender_ID = 0x01000005;
        continueModel.Receiver_ID = 0x2900AB12;
        continueModel.Ussd_Version = 0x20;
        continueModel.Ussd_Op_Type = 0x01;
        continueModel.MsIsdn = "08098765476";
        continueModel.Service_Code = "*308";
        continueModel.Code_Scheme = 0x44;
        continueModel.Ussd_Content = "1. Continue if you are 18+ 2. Exit i";



我不断收到错误类型:USSDcontinueModel不能被编组为一个非托管的结构;任何有意义的大小或偏移可以计算。

I keep getting the error "Type: USSDcontinueModel cannot be marshalled as an unmanaged structure; no meaningful size or offset can be computed".

我注意到这种情况时,我设置Ussd_Version,Ussd_Op_Type和Code_Scheme为[的MarshalAs(UnmanagedType.U1)],但它工作正常[的MarshalAs (UnmanagedType.U4)。

I noticed this happens when i set the Ussd_Version, Ussd_Op_Type and Code_Scheme as [MarshalAs(UnmanagedType.U1)] but it works fine with [MarshalAs(UnmanagedType.U4)].

时[的MarshalAs(UnmanagedType.U1)unmarshallable? ?我该怎么办

Is [MarshalAs(UnmanagedType.U1)] unmarshallable? what do i do?

推荐答案

的问题是定义的:

[MarshalAs(UnmanagedType.U1)]
public uint Ussd_Op_Type;



是模糊的,以什么规模的会员可以。如果互操作名帅使用成员的规模,它会计算4个字节,而如果使用了的MarshalAs 属性,它将计算1个字节。更改成员使用正确的尺寸类型,

is ambiguous as to what size the members could be. If the interop marshal uses the member's size, it will calculate 4 bytes, whereas if it uses the MarshalAs attribute it will calculate 1 byte. Changing the member to use the correct size type,

[MarshalAs(UnmanagedType.U1)]
public byte Ussd_Op_Type;



应该解决这个问题。

should fix the issue.

这篇关于一个编组C#结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆