#c_sharp #net #unsafe
Пробую перенести одну из структур с из DXGI, но столкнулся с проблемой. Определение структуры typedef struct DXGI_GAMMA_CONTROL { DXGI_RGB Scale; DXGI_RGB Offset; DXGI_RGB GammaCurve[1025]; } DXGI_GAMMA_CONTROL, *LPDXGI_GAMMA_CONTROL; Хорошо, пробую перенести: Структура DxgiRbg: ////// Represents an RGB color. /// [StructLayout(LayoutKind.Sequential)] public struct DxgiRgb { ////// A value representing the color of the red component. The range of this value is between 0 and 1. /// public float Red; ////// A value representing the color of the green component. The range of this value is between 0 and 1. /// public float Green; ////// A value representing the color of the blue component. The range of this value is between 0 and 1. /// public float Blue; } Проблемная структура: ////// Controls the settings of a gamma curve. /// public struct DxgiGammaControl { ////// A public DxgiRgb Scale; ///structure with scalar values that are applied to rgb values before being sent to the gamma /// look up table. /// /// A public DxgiRgb Offset; ///structure with offset values that are applied to the rgb values before being sent to the /// gamma look up table. /// /// An array of private unsafe fixed DxgiRgb GammaCurve[1025]; } Проблема с определением поля private unsafe fixed DxgiRgb GammaCurve[1025]; т.к. массивы фиксированной длины могут быть только из стандартных типов int, short, byte и т.д. Как перенести такой массив кроме как выделением общего кол-ва байт под весь массив фиксированным полем? fixed byte gammaCureve[Size_All_1025_Structs]; Ведь тут будут накладные расходы времени на вычисление позиции структур на основе их размеров и индекса который был запрошен. Или завести стурктуру с общим объемом требуемой памяти и читать дынные из нее? UPD: Одно из придуманных мной извращений выглядит так: Структура помощник: [StructLayout(LayoutKind.Explicit, Size = 12300)] internal unsafe struct GammaCurveStructArrayHelper { internal DxgiRgb ReadById(int index) { fixed (GammaCurveStructArrayHelper* fixedThisPtr = &this) { IntPtr startData = new IntPtr(fixedThisPtr); return Marshal.PtrToStructurestructures that control the points of a gamma curve. /// (IntPtr.Add(startData, index * HelperDataGet.SizeStruct)); } } internal void ReadAllArrayData(out DxgiRgb[] arrayDxgiRgb) { arrayDxgiRgb = new DxgiRgb[1025]; for (int i = 0; i < 1025; i++) ReadOutWithId(i, out arrayDxgiRgb[i]); } internal void ReadOutWithId(int index, out DxgiRgb dxgiRgb) { fixed (GammaCurveStructArrayHelper* fixedThisPtr = &this) { IntPtr startData = new IntPtr(fixedThisPtr); dxgiRgb = Marshal.PtrToStructure (IntPtr.Add(startData, index * HelperDataGet.SizeStruct)); } } internal void WriteDataById(int index, DxgiRgb dxgiRgb) { fixed (GammaCurveStructArrayHelper* fixedThisPtr = &this) { IntPtr writeIdPtr = IntPtr.Add(new IntPtr(fixedThisPtr), index * HelperDataGet.SizeStruct); IntPtr rgbPtr = new IntPtr(&dxgiRgb); Marshal.Copy(rgbPtr, new[] {writeIdPtr}, 0, HelperDataGet.SizeStruct); } } internal void WriteDataArray(DxgiRgb[] array) { if (array == null) throw new ArgumentNullException(nameof(array)); if (array.Length < 1025 || array.Length > 1025) throw new ArgumentException( "Writable array cannot be greater than 1025 element and less than 1025 elements!", nameof(array)); for (int i = 0; i < 1025; i++) WriteDataById(i, array[i]); } } internal struct HelperDataGet { internal const int SizeStruct = 12; } И реализация чтения/записи: /// /// Controls the settings of a gamma curve. /// public struct DxgiGammaControl { ////// A public DxgiRgb Scale; ///structure with scalar values that are applied to rgb values before being sent to the gamma /// look up table. /// /// A public DxgiRgb Offset; #pragma warning disable 649 private GammaCurveStructArrayHelper _helper; #pragma warning restore 649 ///structure with offset values that are applied to the rgb values before being sent to the /// gamma look up table. /// /// An array of public DxgiRgb[] GammaCurve { get { _helper.ReadAllArrayData(out DxgiRgb[] arrayData); return arrayData; } set => _helper.WriteDataArray(value); } }structures that control the points of a gamma curve. ///
Ответы
Ответ 1
[StructLayout(LayoutKind.Sequential)] public struct DxgiGammaControl { public DxgiRgb Scale; public DxgiRgb Offset; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1025)] public DxgiRgb[] GammaCurve; } https://docs.microsoft.com/ru-ru/dotnet/framework/interop/default-marshaling-for-arrays#arrays-within-structures
Комментариев нет:
Отправить комментарий