这些C ++结构的C#等价物是什么

typedef union _Value { signed char c; unsigned char b; signed short s; unsigned short w; signed long l; unsigned long u; float f; double *d; char *p; } Value; typedef struct _Field { WORD nFieldId; BYTE bValueType; Value Value; } Field; typedef struct _Packet { WORD nMessageType; WORD nSecurityType; BYTE bExchangeId; BYTE bMarketCenter; int iFieldCount; char cSymbol[20]; Field FieldArr[1]; } Packet; 

这些C ++结构的C#等价物是什么?

我正在将一些代码从C ++迁移到C#,并且在迁移这些结构时遇到问题。 我曾尝试过一些东西,但我总是遇到编组问题。

我假设’char’被用作8位数,如果是这样,那么这里是你的映射:

 signed char c; -> SByte c; unsigned char b; -> Byte b; signed short s; -> Int16 s; unsigned short w; -> UInt16 w; signed long l; -> Int32 l; unsigned long u; -> UInt32 u; float f; -> Single f; (though 'float' still works) double *d; -> Double d; (was this meant to be a pointer???) char *p; -> String s; (assuming its a string here, in the marshaling you can tell it whether it is ASCII or wide char format) 

有了这些信息,翻译这些结构应该相对容易(只需确保将它们保存为结构并赋予它属性“[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]”,这将确保编组器以相同的顺序保存所有数据。

另外,我建议查看System.Runtime.InteropServices中的类和属性,因为它们提供了很多方法来自动将数据封送到c / c ++代码(并且它也不需要“不安全”的c#代码)。

有关PInvoke的编组结构,请参阅此MSDN文章 。

关键是使用StructLayout属性来确保PInvoke正确处理结构,并确保不完全排列的类型的MarshalAs属性。

其他一些post已经有很多信息,我想我会分享一个快速提示。 我最近不得不经历这样的问题。 这可能是显而易见的但是如果你将代码拥有到接口的两边,我发现除了一个字段之外的所有内容都要注释掉并且确保工作然后逐个缓慢地添加它们是一种更加安全的方式来实现这一点。

回到.Net 2.0天,我还有一个网络套接字,并将字节流转换为有意义的结构。 此时,唯一的解决方案是使用BitConverter和Buffer类手动完成。

不幸的是我再也找不到网上的例子了。 所以我剥夺了我的老class(天哪,这看起来很古老,丑陋……)。 也许由于条带下降,其中存在一些小错字错误,但它应该让您对如何解决问题有个好主意。

 using System; using System.Collections.Generic; using System.Text; namespace VehicleSpeedTracer { public class Datagram { //Offsets im ByteArray private const int SizeOffset = 0; private const int TimeOffset = SizeOffset + sizeof(uint); private const int SpeedOffset = TimeOffset + sizeof(double); private const int UnitOffset = SpeedOffset + sizeof(char); private const int UnitMaxSize = (int)MaxSize - UnitOffset; //Daten Current public const uint MaxSize = 128; public TimeSpan CurrentTime; public double CurrentSpeed; public string Unit; public uint Size { get { return MaxSize - (uint)UnitMaxSize + (uint)Unit.Length; } } public Datagram() { } public Datagram(Datagram Data) { CurrentTime = Data.CurrentTime; CurrentSpeed = Data.CurrentSpeed; Unit = Data.Unit; } public Datagram(byte[] RawData) { CurrentTime = TimeSpan.FromSeconds(GetDouble(RawData, TimeOffset)); CurrentSpeed = GetDouble(RawData, SpeedOffset); Unit = GetString(RawData, UnitOffset, (int)(GetUInt(RawData, SizeOffset) - UnitOffset)); } public override string ToString() { return this.CurrentTime.Hours.ToString().PadLeft(2, '0') + ":" + this.CurrentTime.Minutes.ToString().PadLeft(2, '0') + ":" + this.CurrentTime.Seconds.ToString().PadLeft(2, '0') + "." + this.CurrentTime.Milliseconds.ToString().PadLeft(3, '0') + " " + this.Unit; } public static implicit operator byte[](Datagram Data) { byte[] RawData; RawData = new byte[Data.Size]; SetUInt(RawData, SizeOffset, Data.Size); SetDouble(RawData, TimeOffset, Data.CurrentTime.TotalDays); SetDouble(RawData, SpeedOffset, Data.CurrentSpeed); SetString(RawData, UnitOffset, Data.Unit); return RawData; } #region Utility Functions // utility: get a uint from the byte array private static uint GetUInt(byte[] aData, int Offset) { return BitConverter.ToUInt32(aData, Offset); } // utility: set a uint into the byte array private static void SetUInt(byte[] aData, int Offset, uint Value) { byte[] buint = BitConverter.GetBytes(Value); Buffer.BlockCopy(buint, 0, aData, Offset, buint.Length); } // utility: get a ushort from the byte array private static ushort GetUShort(byte[] aData, int Offset) { return BitConverter.ToUInt16(aData, Offset); } // utility: set a ushort into the byte array private static void SetUShort(byte[] aData, int Offset, int Value) { byte[] bushort = BitConverter.GetBytes((short)Value); Buffer.BlockCopy(bushort, 0, aData, Offset, bushort.Length); } // utility: get a double from the byte array private static double GetDouble(byte[] aData, int Offset) { return BitConverter.ToDouble(aData, Offset); } // utility: set a double into the byte array private static void SetDouble(byte[] aData, int Offset, double Value) { byte[] bushort = BitConverter.GetBytes(Value); Buffer.BlockCopy(bushort, 0, aData, Offset, bushort.Length); } // utility: get a unicode string from the byte array private static string GetString(byte[] aData, int Offset, int Length) { String sReturn = Encoding.ASCII.GetString(aData, Offset, Length); return sReturn; } // utility: set a unicode string in the byte array private static void SetString(byte[] aData, int Offset, string Value) { byte[] arr = Encoding.ASCII.GetBytes(Value); Buffer.BlockCopy(arr, 0, aData, Offset, arr.Length); } #endregion } public delegate void DatagramEventHandler(object sender, DatagramEventArgs e); public class DatagramEventArgs : EventArgs { public Datagram Data; public DatagramEventArgs(Datagram Data) { this.Data = Data; } } }