C++ で書かれたアンマネージ ライブラリのラッパーを書こうとしています。DllImport
ライブラリのコーダーは、次のような sを含む C# ラッパーの例を教えてくれました。
[DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)]
internal static extern int doSomething(int inputArraySize, byte* inputArrayPointer, out int outputInteger, out int outputArraySize, out float* outputArrayPointer);
public static int DoSomething(byte[] inputArray, out int outputInteger, out float[] outputArray)
{
int arraySize = inputArray.Length;
int outputArraySize;
float* outputArrayPointer;
outputArray = null;
fixed (byte* arrayPointer = inputArray)
{
int result = doSomething(arraySize, arrayPointer, out outputInteger, out outputArraySize, out outputArrayPointer);
if (result == 0)
{
outputArray = new float[outputArraySize];
for (int i = 0; i < outputArraySize; i++)
{
outputArray[i] = outputArrayPointer[i];
}
// This is another imported function.
freePointer(outputArrayPointer);
}
}
return result;
}
彼はコードで を使用していますが、安全でないコードとポインターをすべてfixed
使用して失うだけでよいのではないかと考えています。ref
次のように書き換えることができます。
[DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)]
internal static extern int doSomething(int arraySize, ref byte[] arrayPointer, out int someInteger, out int outputArraySize, out float[] someArrayPointer);
public static int DoSomething(byte[] inputArray, out int outputInteger, out float[] outputArray)
{
int outputArraySize;
int result = doSomething(inputArray.Length, ref inputArray, out outputInteger, out outputArraySize, out outputArray);
return result;
}
上記のコードは、ポインターを使用した最初のコードと意味が同じですか?
- 私のバージョンを使用しても大丈夫ですか?
- 私のバージョンを使用することの欠点はありますか?
- を使用する場合
ref
、管理されていない libraray 関数に渡された配列は、関数の実行中ずっと安全ですか? - そして、その機能は何をしていると思います
freePointer()
か? とにかく、ポインタはガベージコレクションによって収集されます。なぜそのような機能が必要なのですか?
この問題に関する提案をいただければ幸いです。
編集:追加のコードなしでは、C++ ポインターを C# 配列として取得することはできないと思います。最善の方法は何ですか?安全でないコードやポインターを使用せずにこれらすべてを行う方法はありますか?
編集 2:freePointer()
この関数は、アンマネージ コードによって割り当てられた配列を解放すると思います。しかし、配列サイズをパラメーターとして取得せずに、ポインターだけで配列を解放するにはどうすればよいでしょうか?