编组C#结构
我试图序列化以下c#结构:
[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(); } }
当我尝试序列化结构的一个实例时说:
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不能作为非托管结构编组;不能计算有意义的大小或偏移量”。
我注意到当我将Ussd_Version,Ussd_Op_Type和Code_Scheme设置为[MarshalAs(UnmanagedType.U1)]时会发生这种情况,但它与[MarshalAs(UnmanagedType.U4)]一起工作正常。
[MarshalAs(UnmanagedType.U1)]是否是无编组的? 我该怎么办?
问题是定义:
[MarshalAs(UnmanagedType.U1)] public uint Ussd_Op_Type;
关于成员的规模是多么模糊。 如果interop marshal使用成员的大小,它将计算4个字节,而如果它使用MarshalAs
属性,它将计算1个字节。 更改成员以使用正确的大小类型,
[MarshalAs(UnmanagedType.U1)] public byte Ussd_Op_Type;
应该解决这个问题。
因此,在采用@ theB建议将U1数据类型声明为字节之后。 问题解决了。 更新的结构定义如下:
上述就是C#学习教程:编组C#结构分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
[Serializable] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack=1)] 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 byte Ussd_Version; [MarshalAs(UnmanagedType.U1)] public byte Ussd_Op_Type; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string MsIsdn; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string Service_Code; [MarshalAs(UnmanagedType.U1)] public byte 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(); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1018328.html