3

C# .NET アプリケーションから呼び出したい C で記述されたレガシー DLL があります。問題は、C DLL の DLL インターフェイスがかなり複雑なことです。それは次のようなものです:

__declspec(dllexport) void __stdcall ProcessChunk(
    void *p_prochdl,
    const BIG_INPUT_STRC *p_inparams,
    BIG_OUTPUT_STRC *p_outparams
);

BIG_INPUT_STRC/BIG_OUTPUT_STRC には、あらゆる種類のものが含まれています...バッファ配列へのポインタ、列挙型パラメータ、整数パラメータなどです。要するに、それらは複雑です。

最初の質問: DLL ヘッダー ファイルに含まれるすべての構造情報を C# クラスに取得する簡単な方法はありますか? それとも、文字通りすべてを C# にコピー アンド ペーストして再定義する必要がありますか? これは冗長に思えます。

それに関連して、C# からアンマネージ DLL に構造体を渡す正しい方法は何ですか?

最後に、バッファー配列を C# からアンマネージ DLL に正しく渡す方法の例はありますか? または、2 次元配列を DLL に渡すにはどうすればよいですか?

ありがとう - グレッグ

4

3 に答える 3

2

.net マーシャリングを広範囲に使用する必要があります。まず、C# コードで C 構造体を再定義する必要があります。次に、MarshalAs属性を使用して、すべてが適切にマーシャルされるようにします。

C# の構造体へのポインターを C 関数に戻す必要がある場合は、Marshal.StructToPtr関数を使用できます。

バッファ配列は、byte[] として定義されていると仮定すると、次の手法を使用してマーシャリングできます。

byte[] buffer = ...;
fixed(byte *pBuffer = buffer)
{
   // do something with the pBuffer
}

fixed ステートメントは、バッファーがガベージ コレクターによってメモリ内で移動されないようにし、ステートメント内のポインターを 'fixed' または 'pinned' にします。

多次元配列に関しては、基になる C 実装に依存します。たとえば、配列へのポインターを操作し、次のように次元数と各次元の要素数に基づいて位置を調整できます。

someValue = buffer[(elementsPerDimensions * x) + y];

あなたの説明からすると、すでにかなり複雑に思えますが、ライブラリを COM フレンドリーにすることを検討しましたか?

于 2009-01-30T04:10:41.370 に答える
0

なんて丸薬。

  1. ライブラリを COM フレンドリーにしようとするのは避けたいと思います。それはその価値よりも面倒です。

  2. 最初のレコードを作成して呼び出すために、P/INVOKED になるように設計された関数を含む 2 つ目のネイティブ ライブラリを構築します。

または、マーシャリングを処理する C++ ネイティブ/マネージ ライブラリを作成することもできます。

于 2009-01-30T04:16:32.513 に答える