2013-03-24 13 views
5

私はC++/CLIで純粋なアンマネージドVC++ 9プロジェクトをラップして、.NETアプリケーションから明快に使用しています。私はwrappersの書き方を知っている、とアンマネージコードcan be executed from .NETことが、何私はかなりの周り私の頭をラップすることはできません。管理対象C++/CLIプロジェクトからアンマネージC++を正常に実行することはできますか?

  1. 管理されていないlibには非常に複雑なC++のライブラリで、インライン化や他の多くを使用しています機能のため、これを/clr-markedマネージド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のどの機能が何らかの影響を受けますか?

+2

はい、混在モードを実行できます。コンパイルしたいファイルを '/ clr'オプションなしでネイティブとしてマークするだけです。関数レベルでこれを制御するための#pragmaディレクティブがいくつかあります。 – leppie

答えて

7
あなたは(うまく十年以上前から言って、から輸入し、Visual Studioの6.0)ネイティブC++プロジェクトを開始することができます

今日ビルドすると、現在のバージョンのVCランタイムにリンクされます。

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

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

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

あなたは宣言で、ヘッダーfoo.hを作る場合:

void bar(int a, int b); 

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

あなたは互換性のないスイッチに関するエラーコンパイルれることがあります。

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

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

+0

驚くようなことです!しかし、どのファイルを '/ clr'とすればよいのでしょうか?プロジェクト設定ダイアログでも、プロジェクト全体に対して '/ clr'を有効にする必要がありますか? –

+0

いいえ、foo.cppのプロパティを表示し、C++セクションに移動し、* Common Language RunTime Support *設定で*共通言語ランタイムサポート(/ clr)を選択します* –

+0

他のオプションをオフにする必要があります - 更新されます。 –

0

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

もあなたに使用のものとすることができるC++相互運用技術があるようです:http://msdn.microsoft.com/en-us/library/2x8kf7zx(v=vs.80).aspx

+0

私はこれを行うことはできないと思います。私は#5でライブラリが非常に複雑で、独自のオブジェクトを管理していると言いました。アクティブなDirectXオブジェクトポインタなどを管理しています。定期的に実行される独自のGCもあります。私は何も壊すことなくこれを包み込みようとしています。 –

+0

静的関数を作成してP/Invokeを使用すると、実際のC++プロジェクトは通常のVC++環境で実行されますか、.NETは関数の実行中に呼び出すだけで終了しますか? –

+0

NB explicit p/invokeはC++/CLIでは必須ではありません。個々の機能のレベルで組み込みのシームレスな相互運用機能を備えています。 –

1

Danielから言われたように、ファイルレベルで設定を微調整できます。また、ファイル内で#pragma managedを使用して再生することもできますが、理由がなければそれを実行しません。

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

これは、ファイル外のネイティブクライアントコードが考慮される限り、エクスポートについてのみ気にすることを意味します。混在したdll /アセンブリ内のC++/CLIコードは、通常のアクセス規則(単にヘッダを含む)を使用してネイティブデータ構造にアクセスできます。

あなたはそれを言いましたので、かなりの量のDirectXコードを含む階層。だから、ここで主要な問題はありません。

.NET駆動環境でpInvokeを使用することはお勧めしません。確かに、それは動作します。しかし、C++/CLIで提供されているように、OOの方がはるかに優れています(10以上の関数)。あなたのC#クライアント開発者は感謝します。デリゲートやプロパティ、管理されたスレッドなど、C++/CLIの指のヒントのすべての.NETのものがあります。いくらか使えるインテリセンスでVS 2012から始める。

関連する問題