いくつかのマネージクラスを含むマネージc++dllがあり、dllに静的にリンクしているライブラリ内のネイティブc++コードを呼び出します。ただし、dllでRegAsm.exeを実行しようとすると、ツールは「登録したタイプがありません」と正しく報告しますが、ハングします。これはローダーロックの問題であり、RegAsmがロードしようとするとdllがハングすることは間違いありません。Visual Studio 2008ExpressEditionを使用しています。
ネイティブコードをdllに配置する場合はすべて正常に機能しますが、ライブラリから静的にリンクする場合は機能しないことに戸惑います。この投稿がこの質問に似ていることは承知していますが、dllにDllMainがありません。DllMainからMSILコードを実行するリスクはありません。また、個々のファイルに/clrを設定するというアドバイスに従うことは役に立ちませんでした。
/ NOENTRYを使用してdllをコンパイルすると、ロックの問題は修正されますが、Type initializer for <Module> threw exception
例外が発生してアプリケーションが破損するため、.NET2003でのみ推奨されるようです。
静的メンバーの初期化が原因である可能性があると思われますが、静的ライブラリでMSILにコンパイルされるのはなぜ私を超えているのでしょうか。
明確にするために:dllでRegAsm.exeを実行する必要はありませんが、ローダーロックの問題のチェックとして使用しています。実際には、COMに表示されるクラスをほとんど実装していないac#アセンブリでdllを使用しているため、そのクラスでCOM登録を行う必要があります。最後に、COM相互運用機能の登録中にC#IDEがクラッシュし、'R6033 c ++ランタイムエラーが報告されます:ネイティブコードの初期化中にこのアセンブリのMSILコードを使用しようとしました。これは、アプリケーションにバグがあることを示しています。これは、ネイティブコンストラクターまたはDllMainからMSILコンパイル済み(/ clr)関数を呼び出した結果である可能性があります。
問題は解決しましたが、不明な点がいくつかあり、興味があります。
動作が停止したときに、静的にリンクされたlibのヘッダーファイルに2つの静的変数が追加されていることに気付きました。これは、次のようになります。
// The whole header is forced to compile as native
#pragma managed(push, off)
....
static const std::locale commaSeparator(std::locale::classic(),
new DecimalSeparator<char>(','));;
....
#pragma managed(pop)
初期化を.cppファイルに移動する(およびに変更static
するextern
)と、ローダーのロックが修正されます。イニシャライザがMSILにコンパイルされる理由を誰かが指摘できますか?
修正前は、マネージdllからヘッダーファイルを#includeしただけで、問題なく動作しました。しかし、ヘッダーを含め、libにもリンクしていると、うまくいきませんでした。libも内部でヘッダーを使用するので、静的変数の2つのインスタンスになりましたか?いずれにせよ、なぜMSILコードの実行に関する苦情があるのでしょうか。
今はうまくいきますが、どんな洞察も歓迎します。