I try to transfer one of the structures from DXGI , but I ran into a problem.

Structure definition

 typedef struct DXGI_GAMMA_CONTROL { DXGI_RGB Scale; DXGI_RGB Offset; DXGI_RGB GammaCurve[1025]; } DXGI_GAMMA_CONTROL, *LPDXGI_GAMMA_CONTROL; 

Well, I try to transfer:

DxgiRbg structure:

 /// <summary> /// Represents an RGB color. /// </summary> [StructLayout(LayoutKind.Sequential)] public struct DxgiRgb { /// <summary> /// A value representing the color of the red component. The range of this value is between 0 and 1. /// </summary> public float Red; /// <summary> /// A value representing the color of the green component. The range of this value is between 0 and 1. /// </summary> public float Green; /// <summary> /// A value representing the color of the blue component. The range of this value is between 0 and 1. /// </summary> public float Blue; } 

Problem structure:

 /// <summary> /// Controls the settings of a gamma curve. /// </summary> public struct DxgiGammaControl { /// <summary> /// A <see cref="DxgiRgb" /> structure with scalar values that are applied to rgb values before being sent to the gamma /// look up table. /// </summary> public DxgiRgb Scale; /// <summary> /// A <see cref="DxgiRgb" /> structure with offset values that are applied to the rgb values before being sent to the /// gamma look up table. /// </summary> public DxgiRgb Offset; /// <summary> /// An array of <see cref="DxgiRgb" /> structures that control the points of a gamma curve. /// </summary> private unsafe fixed DxgiRgb GammaCurve[1025]; } 

The problem with the definition of the field

 private unsafe fixed DxgiRgb GammaCurve[1025]; 

because Fixed-length arrays can only be of standard types int , short , byte , etc.

How to transfer such an array except by allocating the total number of bytes under the entire array with a fixed field?

 fixed byte gammaCureve[Size_All_1025_Structs]; 

After all, there will be overhead time to calculate the position of the structures based on their size and the index that was requested.

Or to get a structure with the total amount of required memory and read melon from it?


UPD:

One of the perversions invented by me looks like this:

Structure Assistant:

 [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.PtrToStructure<DxgiRgb>(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<DxgiRgb>(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; } 

And the implementation of read / write:

 /// <summary> /// Controls the settings of a gamma curve. /// </summary> public struct DxgiGammaControl { /// <summary> /// A <see cref="DxgiRgb" /> structure with scalar values that are applied to rgb values before being sent to the gamma /// look up table. /// </summary> public DxgiRgb Scale; /// <summary> /// A <see cref="DxgiRgb" /> structure with offset values that are applied to the rgb values before being sent to the /// gamma look up table. /// </summary> public DxgiRgb Offset; #pragma warning disable 649 private GammaCurveStructArrayHelper _helper; #pragma warning restore 649 /// <summary> /// An array of <see cref="DxgiRgb"/> structures that control the points of a gamma curve. /// </summary> public DxgiRgb[] GammaCurve { get { _helper.ReadAllArrayData(out DxgiRgb[] arrayData); return arrayData; } set => _helper.WriteDataArray(value); } } 

    1 answer 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

    • It seems that this attribute will solve a few more of my problems =) - LLENN