Ответ 1
Если для этого требуется только указатель, вы можете выделить некоторую неуправляемую память, упорядочить структуру в памяти и передать этот указатель на свою функцию. Затем после этого вы можете вернуться к структуре (если хотите) и освободить память. Прежде чем вы производите все, вам нужно правильно определить структуру. Что-то вроде этого:
[StructLayout(
LayoutKind.Sequential, //must specify a layout
CharSet = CharSet.Ansi)] //if you intend to use char
public struct ToBePassed
{
public Int32 Num1;
public Int32 Num2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public Char[] Data; //specify the size using MarshalAs
}
[DllImport("...")]
public static extern void APICall(IntPtr argPtr);
public static void CallFunction(ToBePassed managedObj)
{
IntPtr unmanagedAddr = Marshal.AllocHGlobal(Marshal.SizeOf(managedObj));
Marshal.StructureToPtr(managedObj, unmanagedAddr, true);
APICall(unmanagedAddr);
Marshal.PtrToStructure(unmanagedAddr, managedObj);
Marshal.FreeHGlobal(unmanagedAddr);
unmanagedAddr = IntPtr.Zero;
}
[править]
Чтобы имитировать массивы переменной длины, выделите неуправляемую память в структуре и инициализируйте, как обычно.
[StructLayout(LayoutKind.Sequential)]
public struct SomeStruct
{
public Int32 X;
public Int32 Y;
}
[StructLayout(LayoutKind.Sequential)]
public struct VLA
{
public Int32 intArrayLength;
public Int32 SomeStructArrayLength;
public IntPtr intArray;
public IntPtr SomeStructArray;
}
public static VLA CreateVLA(int[] intArray, SomeStruct[] SomeStructArray)
{
var vla = new VLA()
{
intArrayLength = intArray.Length,
SomeStructArrayLength = SomeStructArray.Length,
intArray = Marshal.AllocHGlobal(intArray.Length * Marshal.SizeOf(typeof(int))),
SomeStructArray = Marshal.AllocHGlobal(SomeStructArray.Length * Marshal.SizeOf(typeof(SomeStruct))),
};
Marshal.Copy(intArray, 0, vla.intArray, intArray.Length);
//there no overload to copy arbitrary arrays, do it manually
for (int i = 0; i < SomeStructArray.Length; i++)
{
Marshal.StructureToPtr(
SomeStructArray[i],
vla.SomeStructArray + i * Marshal.SizeOf(typeof(SomeStruct)),
true);
}
return vla;
}