5

.NETアプリからわかりやすく使用するために、純粋なアンマネージドVC++9プロジェクトをC++/CLIでラップしているところです。私はラッパーの書き方を知っており、アンマネージコードは.NETから実行できますが、頭を完全に包み込むことができないものは次のとおりです。

  1. アンマネージライブラリは非常に複雑なC++ライブラリであり、多くのインライン化やその他の機能を使用するため、これをマーク付きの/clrマネージDLLにコンパイルすることはできません。通常のVC++コンパイラを使用して、これを別のDLLにコンパイルする必要があります。

  2. このアンマネージコードからシンボルをエクスポートして、C ++ / CLIプロジェクトから使用できるようにするにはどうすればよいですか?表示する必要があるすべてのクラスをマークしexternますか?それはそれほど単純ですか、それとももっと複雑ですか?

  3. C ++ / CLIプロジェクトからエクスポートされたシンボルにアクセスするにはどうすればよいですか?アンマネージソースコードのヘッダーファイルをインクルードするだけで、C ++リンカーはアンマネージDLLから実際のコードを取得しますか?または、DLL内のクラスを指す新しいヘッダーファイルに「extern」クラスの個別のセットを手書きで書き込む必要がありますか?

  4. 私のC++/ CLIプロジェクトがアンマネージクラスを作成するとき、アンマネージコードは通常のVC9ランタイムで完全に正常に実行されますか、それとも.NET内で強制的に実行されますか?より多くの互換性の問題を引き起こしますか?

  5. C ++プロジェクトは、多くのインスタンスを作成し、独自のカスタム実装のガベージコレクターを備えており、すべてプレーンC ++で記述されています。これは、DirectXサウンドレンダラーであり、多くのDirectXオブジェクトを管理します。これはすべて正常に機能しますか、それともそのようなWin32機能は何らかの形で影響を受けますか?

4

3 に答える 3

8

通常のネイティブC++プロジェクト(たとえば、10年以上前のVisual Studio 6.0からインポートされたもの)から始めることができ、今日それをビルドすると、VCランタイムの現在のバージョンにリンクします。

次に、新しいファイルを1つ追加できますfoo.cppが、/CLRフラグが有効になるようにそのファイルを構成します。これにより、コンパイラはその1つのファイルからILを生成し、追加のサポートにリンクして、起動時に.NET Frameworkをプロセスにロードし、JITコンパイルしてILを実行できるようにします。

アプリケーションの残りの部分は、以前と同じようにネイティブにコンパイルされ、まったく影響を受けません。

真実は、CLR自体が(明らかに)ネイティブコードであるため、「純粋な」CLRアプリケーションでさえ実際にはハイブリッドであるということです。混合C++/ CLIアプリケーションは、CLRでホストされているコードとプロセスを共有するネイティブコードを追加できるようにすることで、これを拡張するだけです。それらはプロセスの存続期間中共存します。

foo.h宣言付きのヘッダーを作成する場合:

void bar(int a, int b);

これは、ネイティブコードまたはfoo.cppCLRコードのいずれかで自由に実装または呼び出すことができます。コンパイラとリンカーの組み合わせがすべてを処理します。CLRコード内からネイティブコードを呼び出すために特別なことをする必要はありません

互換性のないスイッチに関するコンパイルエラーが発生する場合があります。

  • /ZI-編集して続行するためのプログラムデータベース、プログラムデータベースのみに変更
  • /Gm-最小限の再構築を無効にする必要があります
  • /EHsc-C ++例外、SEH例外(/ EHa)でYesに変更
  • /RTC-ランタイムチェック、デフォルトに変更
  • プリコンパイル済みヘッダー-プリコンパイル済みヘッダーを使用しないに変更します
  • /GR--実行時型情報-オン(/ GR)に変更します

これらの変更はすべて、特定の/CLR対応ファイルに対してのみ行う必要があります。

于 2013-03-24T12:49:10.747 に答える
1

ダニエルから述べたように、ファイルレベルで設定を微調整することができます。ファイル内の「#pragmamanaged」で遊ぶこともできますが、理由がなければそうしません。

完全な混合モードアセンブリを作成できることを覚えておいてください。つまり、ネイティブコードを変更せずにこのファイルにコンパイルし、さらにこのコードのC ++/CLIラッパーをコンパイルすることができます。最後に、エクスポートされたすべてのネイティブシンボルを含むネイティブDLLと同じファイルと、本格的な.NETアセンブリ(C ++ / CLIオブジェクトを公開)として同時に使用できます。

つまり、ファイル外のネイティブクライアントコードが考慮される限り、エクスポートについてのみ気にする必要があります。混合dll/アセンブリ内のC++/ CLIコードは、通常のアクセスルール(ヘッダーを含めるだけで提供されます)を使用してネイティブデータ構造にアクセスできます。

あなたがそれを言ったので、私はかなりの量のDirectXコードを含むいくつかの重要なネイティブC++クラス階層のためにこれをしました。したがって、ここでは大きな問題はありません。

.NET駆動型環境でのpInvokeの使用はお勧めしません。確かに、それは機能します。ただし、重要なもの(たとえば、10個を超える関数)の場合は、C ++/CLIで提供されるオブジェクト指向アプローチの方が確かに優れています。C#クライアント開発者は感謝するでしょう。C ++ / CLIでは、デリゲート/プロパティ、マネージスレッドなど、すべての.NET機能をすぐに利用できます。ある程度使用可能なIntellisenseを備えたVS2012から開始します。

于 2013-03-24T19:41:50.033 に答える
0

PInvokeを使用して、アンマネージDLLからエクスポートされた関数を呼び出すことができます。これは、管理されていないWindowsAPIに.Netからアクセスする方法です。ただし、エクスポートされた関数がプレーンなCデータ構造だけでなく、C ++オブジェクトを使用している場合は、問題が発生する可能性があります。

http://msdn.microsoft.com/en-us/library/2x8kf7zx(v=vs.80).aspx:あなたに役立つC++相互運用技術もあるようです。

于 2013-03-24T12:31:39.440 に答える