アンマネージ コードでメモリを割り当て、マネージ側で 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);
}
データが実際に文字列であったかどうか、または不透明なバイナリ データを保持するために stringbuffer を使用していたかどうかを指定しませんでした。応答データが null で終わる文字列の場合、単純な配列の代わりにPtrToStringUni
orを簡単に使用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);
}
注: このコードはテストしていないため、小さな省略やバグがある可能性があります...