If you're using P/Invoke and you want to pass a list of elements to a C function, you can use attributes in most cases to have the work done for you. Eg.
[DllImport("x.dll")]
extern void PassDoubleArray([MarshalAs(UnmanagedType.LPArray)]Double[] array);
If you have something a bit more complex and need to do it manually, the Marshal
class has most of what you need to get it done.
First, allocate some unmanaged memory - enough to store your object or array, using Marshal.AllocHGlobal
, which will give you an IntPtr
. You can copy .NET primitives to and from the unmanaged memory by using Marshal.Copy.
For non primitives, create structs and use Marshal.StructureToPtr
to get an IntPtr for it. When you're done with the unmanaged memory, make a call to Marshal.FreeHGlobal
to free it up.
eg, this will do the equivalent of the above attribute, but more long-winded.
[DllImport("x.dll")]
extern void PassDoubleArray(IntPtr array);
List<Double> vals = new List<Double>() { ... }
IntPtr unmanaged = Marshal.AllocHGlobal(vals.Length * sizeof(Double));
Marshal.Copy(vals.ToArray(), 0, unmanaged, vals.Length);
PassDoubleArray(unmanaged);
Marshal.FreeHGlobal(unmanaged);