MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Выравнивание структур для целевой платформы - x64"
Answer 914756
Смещения полей в данном случае не зависят от платформы, ведь в структуре нет ни одного указателя. Но дело в том, что .NET по какой-то причине не разрешает работать с некорректно выровненными массивами в структурах при использовании LayoutKind.Explicit. Вам нужно либо использовать
StructLayout(LayoutKind.Sequential, Pack = 1)
и избавиться от явных смещений, либо включить unsafe-код и объявлять все массивы так:[FieldOffset(20)] public fixed byte flags[4];
Полный код:
using System; using System.Runtime.InteropServices; using System.Text; namespace ConsoleApp1 { class Program { public static T ToObject<T>(byte[] structureDataBytes) { T createdObject = default(T); var memoryObjectSize = Marshal.SizeOf(typeof(T)); // Cannot create object from array that is too small. if (memoryObjectSize > structureDataBytes.Length) return createdObject; // Reserve unmanaged memory, copy structureDataBytes bytes to there, and convert this unmanaged memory to a managed type. // Then free memory. var reservedMemPtr = Marshal.AllocHGlobal(memoryObjectSize); Marshal.Copy(structureDataBytes, 0, reservedMemPtr, memoryObjectSize); createdObject = (T)Marshal.PtrToStructure(reservedMemPtr, typeof(T)); Marshal.FreeHGlobal(reservedMemPtr); return createdObject; } static void Main(string[] args) { byte[] arr = new byte[2000]; arr[0] = 1; arr[1] = 0; arr[2] = 0; arr[3] = 0; Ets2SdkData data = ToObject<Ets2SdkData>(arr); Console.WriteLine(data.time.ToString()); Console.ReadKey(); } } [StructLayout(LayoutKind.Explicit, Pack = 1)] public unsafe struct Ets2SdkData { [FieldOffset(0)] public uint time; [FieldOffset(4)] public uint paused; [FieldOffset(8)] public uint ets2_telemetry_plugin_revision; [FieldOffset(12)] public uint ets2_version_major; [FieldOffset(16)] public uint ets2_version_minor; //***** REVISION 1 ****** // [FieldOffset(20)] public fixed byte flags[4]; //vehicle dynamics [FieldOffset(24)] public float speed; [FieldOffset(28)] public float accelerationX; [FieldOffset(32)] public float accelerationY; [FieldOffset(36)] public float accelerationZ; [FieldOffset(40)] public float coordinateX; [FieldOffset(44)] public float coordinateY; [FieldOffset(48)] public float coordinateZ; [FieldOffset(52)] public float rotationX; [FieldOffset(56)] public float rotationY; [FieldOffset(60)] public float rotationZ; //drivetrain essentials [FieldOffset(64)] public int gear; [FieldOffset(68)] public int gears; [FieldOffset(72)] public int gearRanges; [FieldOffset(76)] public int gearRangeActive; [FieldOffset(80)] public float engineRpm; [FieldOffset(84)] public float engineRpmMax; [FieldOffset(88)] public float fuel; [FieldOffset(92)] public float fuelCapacity; [FieldOffset(96)] public float fuelRate; [FieldOffset(100)] public float fuelAvgConsumption; // user input [FieldOffset(104)] public float userSteer; [FieldOffset(108)] public float userThrottle; [FieldOffset(112)] public float userBrake; [FieldOffset(116)] public float userClutch; [FieldOffset(120)] public float gameSteer; [FieldOffset(124)] public float gameThrottle; [FieldOffset(128)] public float gameBrake; [FieldOffset(132)] public float gameClutch; //truck & trailer [FieldOffset(136)] public float truckWeight; [FieldOffset(140)] public float trailerWeight; [FieldOffset(144)] public int modelOffset; [FieldOffset(148)] public int modelLength; [FieldOffset(152)] public int trailerOffset; [FieldOffset(156)] public int trailerLength; //***** REVISION 2 ****** // [FieldOffset(160)] public int timeAbsolute; [FieldOffset(164)] public int gearsReverse; [FieldOffset(168)] public float trailerMass; [FieldOffset(172)] public fixed byte trailerId[64]; [FieldOffset(236)] public fixed byte trailerName[64]; [FieldOffset(300)] public int jobIncome; [FieldOffset(304)] public int jobDeadline; [FieldOffset(308)] public fixed byte jobCitySource[64]; [FieldOffset(372)] public fixed byte jobCityDestination[64]; [FieldOffset(436)] public fixed byte jobCompanySource[64]; [FieldOffset(500)] public fixed byte jobCompanyDestination[64]; //***** REVISION 3 ****** // [FieldOffset(564)] public int retarderBrake; [FieldOffset(568)] public int shifterSlot; [FieldOffset(572)] public int shifterToggle; [FieldOffset(576)] public int fill; [FieldOffset(580)] public fixed byte aux[24]; [FieldOffset(604)] public float airPressure; [FieldOffset(608)] public float brakeTemperature; [FieldOffset(612)] public int fuelWarning; [FieldOffset(616)] public float adblue; [FieldOffset(620)] public float adblueConsumption; [FieldOffset(624)] public float oilPressure; [FieldOffset(628)] public float oilTemperature; [FieldOffset(632)] public float waterTemperature; [FieldOffset(636)] public float batteryVoltage; [FieldOffset(640)] public float lightsDashboard; [FieldOffset(644)] public float wearEngine; [FieldOffset(648)] public float wearTransmission; [FieldOffset(652)] public float wearCabin; [FieldOffset(656)] public float wearChassis; [FieldOffset(660)] public float wearWheels; [FieldOffset(664)] public float wearTrailer; [FieldOffset(668)] public float truckOdometer; [FieldOffset(672)] public float cruiseControlSpeed; [FieldOffset(676)] public fixed byte truckMake[64]; [FieldOffset(740)] public fixed byte truckMakeId[64]; [FieldOffset(804)] public fixed byte truckModel[64]; // ***** REVISION 4 ****** // [FieldOffset(868)] public float speedLimit; [FieldOffset(872)] public float routeDistance; [FieldOffset(876)] public float routeTime; [FieldOffset(880)] public float fuelRange; [FieldOffset(884)] public fixed float gearRatioForward[24]; [FieldOffset(980)] public fixed float gearRatioReverse[8]; [FieldOffset(1012)] public float gearRatioDifferential; [FieldOffset(1016)] public int gearDashboard; [FieldOffset(1020)] public byte onJob; [FieldOffset(1021)] public byte jobFinished; } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.