GCHandle.Alloc
"Выделяет дескриптор Normal для указанного объекта" , который "создает дескриптор управляемого объекта ..., который не позволяет управляемому объекту собирать ".
То, что вы ищете, это методы из System.Runtime.InteropServices.Marshal
, которые позволяют вам делать такие вещи, как копирование управляемых объектов в память, доступную для неуправляемого кода. К сожалению, согласно this , указатели в вашей структуре затрудняют маршалинг, чем многие другие вещи (в том смысле, что многие другие вещи могут автоматически маршалироваться с использованием соответствующих атрибутов P / Invoke), но это все еще возможно. Я попробовал это, и это работает:
APP_PARAM param = new APP_PARAM();
string[] text = new string[] { "A", "B", "C" };
param.numData = text.Length;
// Manually allocate an array of pointers, one for each string. arr holds the array's address.
IntPtr arr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * text.Length);
try
{
param.text = arr;
IntPtr[] unmanagedText = new IntPtr[text.Length];
try
{
// Create a null-terminated ANSI string in unmanaged memory for each element in text.
for (int i = 0; i < text.Length; i++)
unmanagedText[i] = Marshal.StringToHGlobalAnsi(text[i]);
// Copy the addresses of the unmanaged strings into the manually allocated array.
// I don't know of any way to make an unmanaged copy of a managed array in one call.
Marshal.Copy(unmanagedText, 0, arr, unmanagedText.Length);
// param now looks like what the C++ code is expecting (except for the array of int).
StartApp(param);
}
finally
{
foreach (IntPtr str in unmanagedText)
Marshal.FreeHGlobal(str);
}
}
finally
{
Marshal.FreeHGlobal(arr);
}
Вам потребуется аналогичный код выделения / освобождения для вашего массива значений int с собственными блоками try / finally, чтобы обеспечить вызов FreeHGlobal.