我会让非托管代码分配内存,然后让托管端通过 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);
}
您没有指定您的数据是否实际上是一个字符串,或者您是否使用字符串缓冲区来保存不透明的二进制数据。如果响应数据是以 null 结尾的字符串,那么您可以轻松地使用PtrToStringUni
orPtrToStringAnsi
来获取 astring
而不是简单的数组:
在非托管方面:
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);
}
注意:我没有测试任何这段代码,所以可能会有一些小的遗漏或错误......