2

C++ 関数を呼び出す C# コードがあります。

C++ 関数は、ポインターで渡されたバッファーを埋める必要があります。ただし、配列は空を返します。

インポート宣言は次のとおりです。

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(char[] arr);

簡略化してハードコードされた値を入力した後のコードは次のようになります。

C# のコード:

char[] arr= new char[10];
ret = LogicInterface.FillArr(arr);

C++ コード:

bool FillArr(char* arr)
{
       int length=10;
       for(int i = 0; i < length; i++) 
       {
              arr[i] = 3; //replaced with some hard coded value
       }
       return true;
}

ただし、配列は空のままです。

助言がありますか?

4

3 に答える 3

1

C++ のコードが返す前に配列をキャッシュしない限り、配列を固定する必要はありません。

あなたの場合、アウト引数と見なすことができるように、参照によって配列を渡す必要があります。

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(ref char[] arr);`
于 2012-04-04T10:22:13.907 に答える
1

配列をネイティブ コードに渡す前に固定する必要があると思います。これにより、C++ でマネージド配列にアクセスしているときに、GC がマネージド配列をメモリ内で移動できなくなります。

したがって、次を使用できます。

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr( char* arr );

その後:

char[] arr = new char[ 10 ];

fixed (char* pinned = arr )
{
    ret = LogicInterface.FillArr( pinned );
}

これを実際にコンパイルして実行したわけではありませんが、続行する方法についていくつかのアイデアが得られるはずです。

于 2012-04-04T10:16:44.553 に答える
-1

このリンクは非常に便利であることがわかりました:

C#: char** 引数を指定して C++ DLL を呼び出す

最終的なコードは次のようになります。

    [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
    static extern bool FillArr([MarshalAs(UnmanagedType.LPStr, ArraySubType = UnmanagedType.LPStr)] StringBuilder args);

        static void Main(string[] args)
        {
            StringBuilder arr = new StringBuilder(9);
            bool res = FillArr(arr);
        }
于 2012-04-04T11:38:45.967 に答える