Я хотел бы, чтобы неуправляемый код выделил память, а затем позволил бы управляемой стороне скопировать ее в управляемый массив через IntPtr и освободить распределение.
Сначала необходимо, чтобы ваша неуправляемая функция возвращала размер выходного массива:
void archive(char * dataChr, char * outChr, int length);
Тогда управляемая сторона должна получить его как IntPtr:
class Archiver {
public static byte[] Archive(string data) {
IntPtr responsePtr = IntPtr.Zero;
int length = 0;
// Call the unmanaged function with our output params
archive(data, responsePtr, length);
byte[] responseArray;
try {
// Create an array for the response
responseArray = new byte[length];
// Copy from unmanaged into managed
Marshal.Copy(responsePtr, responseArray, 0, length);
} finally {
// Free the unmanaged memory once copied
Marshal.FreeHGlobal(responsePtr);
}
return responseArray;
}
[DllImport("Archiver.dll")]
private static extern void archive(string data, [Out]IntPtr encoded, [Out]int length);
}
Вы не указали, были ли ваши данные на самом деле строкой или вы использовали строковый буфер для хранения непрозрачных двоичных данных. Если данные ответа являются строкой с нулевым символом в конце, вы можете легко использовать PtrToStringUni
или PtrToStringAnsi
, чтобы получить string
вместо простого массива:
На неуправляемой стороне:
void archive(char * dataChr, char * outChr);
На управляемой стороне:
class Archiver {
public static string Archive(string data) {
IntPtr responsePtr = IntPtr.Zero;
// Call the unmanaged function with our output params
archive(data, responsePtr);
string responseString;
try {
// Marshal the string from unmanaged SZ String
responseString = Marshal.PtrToStringAnsi(responsePtr);
} finally {
// Free the unmanaged memory once copied
Marshal.FreeHGlobal(responsePtr);
}
return responseString;
}
[DllImport("Archiver.dll")]
private static extern void archive(string data, [Out]IntPtr encoded);
}
NB. Я не тестировал ни один из этих кодов, поэтому могут быть небольшие упущения или ошибки ...