2011-08-10 1 views
1

DLLのマネージC#メソッドを呼び出すアンマネージC++関数があります。 C#メソッドの目的は、(C++呼び出し元によって割り当てられた)バイト配列を取得し、配列にデータを格納して戻すことです。配列をC#メソッドに入れることはできますが、データがC++関数に戻ったときにデータが失われてしまいます。今のところ、これは、プロセスをデバッグするために私のテストコードです:C++ <-->マーシャルされたバイトの配列を変更します。

C#DLL方法:

// Take an array of bytes and modify it 
public ushort GetBytesFromBlaster([MarshalAs(UnmanagedType.LPArray)] byte[] dataBytes) 
{ 
    dataBytes[0] = (byte)'a'; 
    dataBytes[1] = (byte)'b'; 
    dataBytes[2] = (byte)'c'; 
    return 3; 
} 

C++ DLLを呼び出す関数:

// bytes[] has been already allocated by its caller 
short int SimGetBytesP2P(unsigned char bytes[]) 
{ 
    unsigned short int numBytes = 0; 
    bytes[0] = 'x'; 
    bytes[1] = 'y'; 
    bytes[2] = 'z'; 
    // bytes[] are {'x', 'y', 'z'} here 
    guiPtr->GetBytesFromBlaster(bytes, &numBytes); 
    // bytes[] SHOULD be {'a', 'b', 'c'} here, but they are still {'x', 'y', 'z'} 
    return(numBytes); 

}

私はそれを信じますC + +ポインタを新しいマネージド配列に変換するのではなく、元のものを変更することです。私はいくつかのバリエーションを "ref"修正プログラムなどを使って試しましたが、運はありません。また、これらのデータはヌルで終了する文字列ではありません。日付バイトは生の1バイト値で、NULLで終了しません。

誰でもこの問題を解決できますか?ありがとう!

スチュアート

答えて

4

自分でマーシャルできます。 C#関数がIntPtr型の値でパラメータを受け入れるようにします。また、配列の長さを示す第2パラメータ。特別なマーシャリング属性は必要ない、または必要としません。

次に、Marshal.Copyを使用して、アンマネージポインタから、割り当てた管理バイト[]配列に配列をコピーします。あなたのことを行い、完了したらMarshal.Copyを使用してC++のアンマネージ配列にコピーし直します。

これらの特定のオーバーロードで始める必要があります:デフォルトのISN場合http://msdn.microsoft.com/en-us/library/w22x2hw6.aspxで説明したように

public ushort GetBytesFromBlaster(IntPtr dataBytes, int arraySize) 
{ 
    byte[] managed = new byte[arraySize]; 
    Marshal.Copy(dataBytes, managed, 0, arraySize); 
    managed[0] = (byte)'a'; 
    managed[1] = (byte)'b'; 
    managed[2] = (byte)'c'; 
    Marshal.Copy(managed, 0, dataBytes, arraySize); 
    return 3; 
} 

はまた、カスタムマーシャラーを実装することができます。たとえば

http://msdn.microsoft.com/en-us/library/ms146625.aspx
http://msdn.microsoft.com/en-us/library/ms146631.aspx

あなたが必要とすることをやっている。しかし、それはより多くの仕事のように見えます。

public ushort GetBytesFromBlaster(
    [MarshalAs(UnmanagedType.LPArray, SizeConst=3)] 
    byte[] dataBytes 
) 

を、デフォルトのマーシャラーはあなたのための残りの作業を行う必要があります

+0

これはトリックでした!ありがとう、ジェームス! –

0

私はあなただけSizeConst属性を追加する必要があると考えています。

関連する問題