The struct needs to look like this:
public struct A
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public double[];
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public uint[] df;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public uint[] dfn;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public IntPtr[] dc;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public float[] dg;
public float g;
public byte gs;
}
The key point is that these arrays are stored inline in the struct and therefore must be marshalled using UnmanagedType.ByValArray
.
The function declaration should be:
[DllImport("DevControl.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int DevConfig (ref A a, int b, uint c, bool[] d);
This does assume that the final parameter is an array rather than a pointer to a single boolean. Only you know that. Note also the calling convention. As written, your unmanaged function is cdecl
. And you do need to specify that in the p/invoke.
Now, the problem that you will face is the 2D array in the struct, dc
. The only way to handle that is to manually allocate and marshal unmanaged memory. You cannot use a double[,]
because that simply does not map to double*[]
. Hence you need IntPtr[]
and then some use of the Marshal
class to finish the job. Exactly how all that is to be done cannot be discerned from the question. It does not specify who allocates the memory.
You state in an update that you want to allocate the double arrays in the C# to pass to the unmanaged code. Some example code for that:
IntPtr[] CreateUnmanagedArrays(double[][] arr)
{
IntPtr[] result = new IntPtr[arr.Length];
for (int i=0; i<arr.Length; i++)
{
result[i] = Marshal.AllocCoTaskMem(arr[i].Length*sizeof(double));
Marshal.Copy(arr[i], 0, result[i], arr[i].Length);
}
return result;
}
void DestroyUnmanagedArrays(IntPtr[] arr)
{
for (int i=0; i<arr.Length; i++)
{
Marshal.FreeCoTaskMem(arr[i]);
arr[i] = IntPtr.Zero;
}
}