0

私はいくつかのextern関数を持っているc++dllを持っています。そしてそのように見える

//C++ Code
void GetData(byte * pData)
{
  byte a[] = {3,2,1};
  pData = a;
}

そして私はデータを取得するためにC#側でこのコードを使用しました:

//C# Code
[DllImport(UnmanagedDLLAddress)]
public static extern void GetData(ref IntPtr pData);

//and use it like
IntPtr pointer = IntPtr.Zero;
GetData(ref pointer);
byte[] data = new byte[3] // <===== think we know size
Marshal.Copy(pointer,data ,0,3);

しかし、常に「ポインタ」はゼロなので、Marshal.Copyは私が間違えたところにnull例外をスローしますか?ty

4

2 に答える 2

5

まず、C++コードが配列をスタックに配置します。ドキュメントをここから開始するには、別の方法で割り当てる必要があります:http: //msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx

次に、pDataは「通常の」値の引数であり、事実上ローカル変数です。あなたはそれに割り当てます、そしてそれは関数が戻るときに忘れられます。値を返す「パラメータ外」にしたい場合は、ポインタへの参照またはポインタへのポインタである必要があります。配列の内容をpDataが指すバッファーに実際にコピーする場合は、memcpyからの関数を使用する必要があります#include <cstring>

于 2012-11-01T08:55:00.797 に答える
3

実際、hydeが言ったように、pDataを「out」パラメーターとして使用します。これは明らかに参照型であり、値型ではないため、呼び出されたメソッドはメモリ割り当てを処理します。「ref」は整数などの値型にのみ使用しました。たとえば、アンマネージメソッドから配列の長さを取得します。

この方法は私にとっては問題なく機能します。さらに、「cdecl」呼び出し規約を使用します。

IntPtr aNewIntArray;
uint aNewIntArrayCount = 0;

NativeMethods.getEntityFieldIntArray(out aNewIntArray, ref aNewIntArrayCount);

int[] aNewIntArrayResult = new int[aNewIntArrayCount];
Marshal.Copy(aNewIntArray, aNewIntArrayResult, 0, (int)aNewIntArrayCount);

メソッド宣言:

[DllImport(SettingsManager.PathToDLL, EntryPoint = "getEntityFieldIntArray", CallingConvention = CallingConvention.Cdecl)]
public static extern ErrorCode getEntityFieldIntArray(out IntPtr aNewIntArray, ref UInt32 aNewIntArrayCount);
于 2012-11-01T10:00:59.447 に答える