web-dev-qa-db-ja.com

C#アプリケーションでのC ++クラスDLLの使用

アンマネージC++ DLLは、単一のクラス(COMではなく、単なるC++クラスです)をインターフェイスとしてエクスポートするだけです。C#でこのクラスを使用したいのですが、単にC#にインポートすることはできません。

私のC#アプリケーションでこのクラスを使用する正しい方法は何ですか?

46
cjserio

クラスFooを想定した簡単な方法:

  1. C++/CLIプロジェクトを作成し、このFooWrapperを呼び出します。
  2. FooWrapperをアンマネージdllに依存させます(ただし、通常はそうします)。
  3. Foo *型のプライベートインスタンスフィールドを1つ含むマネージクラスManagedFooを作成します。
  4. 基になるインスタンスフィールドに転送するManagedFooのパブリックラッピング関数を提供します。
  5. オプション(推奨ですが):
    • パラメータを.netイディオム(文字列など)からC++イディオム(std :: stringまたはchar *)に変換する
    • 管理されていない例外をキャッチし、代わりに管理された例外をスローする

次に、C#コードをFooWrapperプロジェクト/ dllに依存させ、アンマネージdllが適切にデプロイされるようにします。その方法はアンマネージdllに依存しますが、通常は同じディレクトリにあれば十分です。

関数がクラスのインスタンスに依存しない場合は、P/Invokeがさらに簡単です

44
ShuggyCoUk

この答えは、単一のクラスライブラリにとってはやり過ぎかもしれませんが、SWIGは、他の言語から使用するC/C++クラスを「ラップ」するための優れたソリューションです。 C#でうまく機能します。

参照http://www.swig.org/ .

8
Stewart

DllImportが最善の策です。特に構造体を渡す場合は、少しのデータ型のマッサージがありますが、ほとんど何でもできます。

3
Steve

管理対象/管理対象外の境界を橋渡しするには、プロキシ(GoFパターン)仲介者が必要です。

2つのオプション:

  • C++/CLIラッパー
  • COMラッパー。

前者はより直接的であり、後者は純粋なC++-> COM-> .NETの2つのステップがあります。

2
Richard

場合によっては、独自のCインターフェイスを提供する方が簡単です。 [〜#〜] swig [〜#〜] はセットアップが簡単です。管理されたC++とC++/CLIを使用しましたが、問題ありません。最も簡単なのは、Cラッパーを実行することでした(ほとんどの言語にはC関数を呼び出す方法があるため、他の言語でも使用できます)。

2
chrish