問題タブ [clr-hosting]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - ホストされた環境のマネージド コードがアンマネージド コードをコールバックできるようにする
Managed.dll を使用するために clr をホストする C# で記述された C++ コードがあります。
この .net には、次のようなメソッドがあり、コードでイベントの通知を登録できます。
インターフェースはこんな感じ
.net の世界でのイベントによってトリガーされる、プログラムの C++ 部分で何かをしたいと思います。必要に応じて、Managed.dll をより C++ に適したものにするためだけに、別のマネージド DLL を作成してもかまいません。
ここでのオプションは何ですか? 私が実装できると確信しているのはこれだけです:
- これらのイベントをリッスンし、それらをキューに入れ、C++ コードがポーリングを介してキューにアクセスできるようにする別のマネージ DLL を作成します。
もちろん、これは「割り込み」スタイルから「ポーリング」スタイルに変わり、すべての長所と短所、およびキューイングを提供する必要があります。ポーリングなしでできますか?どうにかしてマネージ コードを呼び出し、引数として C++ の世界への関数ポインターを提供することはできますか?
更新 stijnの回答とコメントのおかげで、正しい方向に少し進んだことを願っていますが、まだ未解決の主な問題は、管理されていない土地からclrホスト環境にfnポインターを渡す方法だと思います。
「int fn(int)」タイプの関数ポインターをマネージド ワールドに渡したいとします。関連する部分は次のとおりです。
マネージド コード(C++/CLI)
アンマネージ コード
spType->InvokeMember_3
呼び出しは結果につながります0x80131512
。
NativeFun へのポインターをマネージ ワールドに渡す方法、または関数の定義方法に問題があるようです。fn ptr の代わりに String^ param を使用すると、CLR 関数を正常に呼び出すことができます。
c# - CLR のクラス ローディング サービス
私はグーグルからトピックを読んで、これを理解しています:
- Windows ローダーは、.net アプリの exe または dll を読み込みます。
- 次に、Windows ローダーはそのプロセスの clr を作成します。
- 次に、アプリケーションへのエントリ ポイントを見つけて呼び出します。
- しかし、その前に clr のクラス ローダー サービスが来て、Main メソッドを含むクラスをロードします。
- そして、jit コンパイルが行われます。
- clr は、gc、例外処理、クラスの読み込みなどのサービスをアプリに提供します。
私の質問は次のとおりです。
.net app clr を実行すると、エントリ ポイントが特定され、実行が開始されます。しかし遭遇すると
その時、私たちのプロセスはクラスローダと呼ばれる CLR のサービスをどのように呼び出すのでしょうか? 同等の MSIL コードは、newobj が clr のクラス ローダー サービスを内部的に呼び出していますか?
c# - C++ での CLR ランタイムのホスティング
コア アプリケーション内で CLR をホストできるようにするプロジェクトの拡張に取り組んでいます。これにより、この拡張機能が内部でロード/アンロードするマネージド拡張機能を管理できるようにする予定です。そうは言っても、アンロードが可能であることを確認するには、別の AppDomains を使用する必要があります。
現在、ドメインをセットアップしてプラグイン ファイルをロードすることはできますが、その時点で行き詰まります。ドメインがロードされたアセンブリ内で自由に関数を呼び出す方法などはわかりません。
エラーチェックなどを除いた、これまでの読み込み設定は次のとおりです。
プラグインと見なされるために、すべてのプラグインが参照および使用する必要があるクラス ライブラリがあります。これまでのところ、継承する基本クラスにすぎません。
次に、拡張機能がそのクラス ライブラリを参照し、それをベースとして使用します。
私が立ち往生しているのは、いくつかのことを行う方法です:
- メインクラスを取得するにはどうすればよいですか?ただし、メインクラスが引き続き処理できるようにするベース内のメソッドを呼び出すベースとしては?
- メインクラスがベースを継承して、有効なプラグインファイルであることを確認するにはどうすればよいですか?
- C++ 側からメソッドを自由に呼び出して、C# プラグインでイベントを発生させる方法。
起動イベントの場合、C++ プラグインは、イベントのレンダリング、コマンド処理など、ロードされると C# プラグインでより多くのものを呼び出します。
私がオンラインで見つけた例のほとんどは、C# 側全体を静的にする必要があることに固有のものであり、これは望ましくありません。また、ほとんどは個別の AppDomains を使用せず、すべてデフォルトで実行されます。特定のプラグインをアンロードできることが制限されるため、これは望ましくありません。
他の情報が不足していて必要な場合は、お気軽にお知らせください。
c++ - _Type :: get_FullNameによって入力されたBSTRを解放する必要がありますか?
私はこのように見えるいくつかのコードを持っています:
そのbstrを解放する必要がありますか?SysFreeString()を解放するにはどうすればよいですか?そうでない場合はなぜですか?
.net - ICorRuntimeHost 経由の AppDomain アクセス
CLR に読み込まれた AppDomains を列挙する必要があります。しかし、アンマネージコード (C++)からそれを行う必要があります。ICorRuntimeHost を使用する必要があると思います。AppDomains 列挙のメソッドが含まれています。ICorRuntimeHost::NextDomain は、現在の AppDomain に対して IUnknown* を返します。コードでCLR サポートを有効にせずにこの AppDomain にアクセスするには、どのインターフェイスを使用する必要がありますか?
.net - CLRホスティング。.net4で_AppDomainsを列挙する方法
管理対象アプリケーション(dotNet 4)に挿入されるCで記述された管理対象外のdllがあります。_AppDomains
このアプリで実行して、いくつかのモジュールをドメインにロードすることを列挙します。インターフェイスを使用してこれを行うことができICorRuntimeHost
ます。ただし、ICorRuntimeHost
は非推奨であり、(http://msdn.microsoft.com/en-en/library/ms164320%28v=vs.100%29.aspxで説明されているように)に置き換えられていICLRRuntimeHost
ます。
_AppDomain
を使用して列挙を実行するにはどうすればよいICLRRuntimeHost
ですか?出来ますか?
debugging - ホストされているときに CLRProfiler が CLR に接続しない
CLR をホストして C# を洗練された「スクリプト」言語として使用するネイティブ Win32 アプリケーションがあります。
メモリ リークが発生したため、Microsoft の CLR Profiler を使用して調査することにしました。(リークが管理されているかどうかはわかりませんが、このツールがそれを明らかにするのに役立つことを望んでいました。)
ただし、CLRProfiler に (ネイティブ) アプリケーションを開始するように指示すると、アプリケーションは常に実行の最初の 1 秒以内に CLR を開始しますWaiting for application to start common language runtime
が、アプリケーションが明らかにマネージド コードを実行しているにもかかわらず、CLRProfiler はプロンプトを表示し続けます。
CLRProfiler は、マネージ専用プログラムが CLR を開始するために使用するスタブによって開始された場合にのみ CLR に接続でき、アプリケーションが明示的にロードされて起動された場合ではありませんMSCOREE.DLL
か? それとも、私は単に何か間違ったことをしていますか?
または、CLRProfiler がうまく機能するように CLR を開始するときに、ネイティブ アプリケーションで実行する必要がある (できれば単純な) ものはありますか?
c# - マネージド コードからの CLR ホスティング?
マネージ アプリケーションからCLR ホスティングを行うことは可能ですか?
ホスティング API はCOMを介して公開されるため、配管が可能になるはずです。
さらに、ランタイムのバージョン 4.0 から、同じプロセスで複数の CLR をホストできるようになりました。
しかし、別の CLR から CLR をブートストラップすることについてはよくわかりません。可能であれば、アンマネージ コードを使用せずに、ネイティブ C++ からのブートストラップと同じくらい簡単な方法で。
どんなポインタでも大歓迎です、ありがとう。
.net - ネイティブ フレーム全体でマネージ例外をキャッチする
マネージ コードによってマネージ例外がスローされ、キャッチされる可能性はありますが、コール スタックにネイティブ フレームが介在している場合はありますか?
これを行うのに問題があります。アプリは 32 ビットのネイティブ コードで、MSCLR 2.0 をホストします (ただし、ほとんどのコードは .NET 3.5 です)。
このスローが行われない限り、アプリケーションは正常に動作します。スローされたときに正確に何が起こるかは、アプリケーションが実行されているシステムによって異なります。
実際のアプリケーションは非常に複雑なので、少なくとも最初は説明のために簡単な概念コードを投稿します。ネイティブ プログラム ( と呼びますNative.exe
) は、 と呼ぶ単一のマネージ プログラムを実行しますManaged.exe
。Managed.exe
C# で記述された内のどこかに、次のものがあります。
MyKernel
は、混合 C++/CLI アセンブリで定義されたマネージ クラスであり、これを と呼びますGlue.dll
。 MyObject
の別のクラスのインスタンスですGlue.dll
。関連するメソッドは次のようになります。
DoSomething
Native.exe
仮想的に呼び出されるC++ 関数です。簡単に言うと、最終的には、 raise を実行するマネージ メソッドにコールバックすることになりGlue.dll
ますMyEvent
。
MyEvent
が発生し、プログラムが 32 ビット Windows XP システムで実行されている場合、意図したとおりに動作し、コンソールに次のように表示されます。
Windows 7 64 ビット システムで実行すると、代わりに次のようになります。
基本的に、例外は何もないところに消えていきます。何も起こらなかったかのように、すべてが実行され続けます。(例外は、ウィンドウの閉じるボタンを押すことに対応するため、ボタンがクリックされていないかのように動作します。)
リモート デスクトップ経由で Windows Server 2012 システムを実行すると、次のようになります。
そして、アプリケーション全体がクラッシュし、「Native.exe が動作を停止しました」というダイアログが表示され、次のようになります。
try
これは、 /がなかったら期待していたものcatch
です。
その環境で VS2008SP デバッガーの下で実行すると、デバッガーは初回例外をキャッチし、それを続行すると未処理の例外としてキャッチします。
DoSomething
ネイティブは最終的に Win32GetMessage
を呼び出してから を呼び出しDispatchMessage
、ネイティブからマネージへのコールバックはウィンドウ プロシージャから呼び出されるコードで発生することに注意してください。そのウィンドウは Direct3D で描画されます。マネージ プログラムは、Native.exe
すべてのウィンドウ操作と描画操作に「カーネル」を使用し、単独で Windows にアクセスすることはありません。
介在する関数はNative.exe
どれも例外をまったくキャッチしません。Win32 API 関数に例外ハンドラがあるかどうかはわかりません。私はそうは思いませんが、システム間で動作がどのように矛盾していたかをおそらく説明できる場合があります。
これは、Server 2012 での実際のコール スタックを大まかに示したもので、繰り返しの項目が切り取られています。
このシステム全体は長い間正常に動作していますが、以前はマネージ/ネイティブ トランジションで例外をスローする必要はありませんでした。ネイティブ ホストがネイティブからマネージドへのコールバックを実行しているかどうかを気にすることなく、マネージド アプリケーション コードが自由に例外をスローおよびキャッチできるようにしたいと考えています。
このようなトランジションで例外をスローすることについてオンラインで見つけたすべての情報は、常にネイティブ例外をキャッチするか、その逆を管理することに関するものです。これはマネージド キャッチ マネージドですが、介在するネイティブ フレームが問題を複雑にしています。
したがって、一般的にこのような投げ方に関する私の質問は次のとおりです。
これは機能するはずですか?Windows XPでも動作しますが、これが明確に定義された動作なのか、単に運が良かったのかはわかりません。
機能する場合、すべてのシステムで機能しない理由として考えられるものは何ですか?
それが機能しない場合は、すべてのマネージド コールバックを拡張してマネージド例外をキャッチし、それらをネイティブ例外でラップし、それをネイティブ関数のマネージド ラッパーでキャッチして、元のマネージド例外をスローする必要があると思います。 . それはたくさんの髪を引っ張るように聞こえます!