2011-11-15 30 views
8

私が作成したC++/CLI混合モードDLLに問題があります。それを終了する.NETアプリケーションが終了すると、例外がスローされます。 DLL_PROCESS_DETACHが実行された後、DLLは自動的に使用して、実行時には、クリーンアップしatexit()/__onexit()関数を登録し、次の例外スロー:私は静的ブースト例外オブジェクトget_static_exception_object()によって登録されているatexit()コールに問題をトレースしてきました終了時に混在モードのC++/CLI DLLが例外をスローする

Unhandled exception at 0x752bb9bc (KernelBase.dll) in psstestm.exe: 
0xC0020001: The string binding is invalid. 

を。

function_to_call 0x0f560410 [email protected][email protected][email protected][email protected][email protected]@@@[email protected]@@[email protected]@[email protected]@[email protected]@YAXXZ void (void)* 

私は静的ブーストを除いて、ほとんどの部分::動的loaderlockを避けるためにリンクされているスレッドのリンクboost_1_47を使用しています。私はまた、動的には、助けていないすべてのブーストのリンクを試みました。また、ブーストのすべてが#pragma unmanagedブロックで囲まれています。

誰かが似たような問題を抱えていたり、解決策を知りたいと思っていますか?ここで

おかげで、マーク

は、例外が発生する直前にコールスタックです:

psscorem.dll!_CRT_INIT(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 413 C 
psscorem.dll!__DllMainCRTStartup(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 526 + 0x11 bytes C 
psscorem.dll!_DllMainCRTStartup(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 476 + 0x11 bytes C 
[email protected]() + 0xde bytes  
[email protected]() + 0xad bytes 
[email protected]() + 0x14 bytes 
[email protected]() + 0x141 bytes  
[email protected]() + 0x74 bytes 
kernel32.dll!749479f5()  
mscoreei.dll!RuntimeDesc::ShutdownAllActiveRuntimes() + 0xc8 bytes 
mscoreei.dll!CLRRuntimeHostInternalImpl::ShutdownAllRuntimesThenExit() + 0x15 bytes  
clr.dll!EEPolicy::ExitProcessViaShim() + 0x66 bytes  
clr.dll!SafeExitProcess() + 0x99 bytes 
clr.dll!DisableRuntime() - 0x1146bb bytes 
clr.dll!EEPolicy::HandleExitProcess() + 0x57 bytes 
[email protected]() + 0x11c bytes 
[email protected]() + 0x1c bytes 
[email protected]() + 0x38 bytes 
[email protected]() + 0x227 bytes 
[email protected]() + 0x8 bytes 
[email protected]@12() + 0x12 bytes  
[email protected]() + 0x27 bytes 
[email protected]() + 0x1b bytes  

答えて

8

私は同じ問題に直面し、exception_ptrに次の関数にそれを追跡するために管理しています.hpp:

template <class Exception> 
    exception_ptr 
    get_static_exception_object() 
     { 
     Exception ba; 
     exception_detail::clone_impl<Exception> c(ba); 
     c << 
      throw_function(BOOST_CURRENT_FUNCTION) << 
      throw_file(__FILE__) << 
      throw_line(__LINE__); 
     static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c))); 
     return ep; 
     } 

ここで問題となる部分は次のとおりです。static exce ption_ptr EP(...

あなただけの静的削除することができ、それが動作するはずです:この機能を使用する方法

template <class Exception> 
    exception_ptr 
    get_static_exception_object() 
     { 
     Exception ba; 
     exception_detail::clone_impl<Exception> c(ba); 
     c << 
      throw_function(BOOST_CURRENT_FUNCTION) << 
      throw_file(__FILE__) << 
      throw_line(__LINE__); 
     exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c))); 
     return ep; 
     } 

は注意、それは別の静的変数に返された静的変数を割り当てます。この関数の実装全体が疑わしいと思われます。おそらく、これについてのサポートを強化するための質問が出されます。

この問題を解決するための他の回避策があります。混合アセンブリの静的変数に関する詳細な分析は、ここで見つけることができます:http://derevyanko.blogspot.com/2009/01/clic.htmlただし、ロシア語のみです。

+0

ありがとうございます!私はこれを永遠に追跡してきました。私はC++を知っていないので、atexitを呼び出す方法を理解するのに十分です。 – pedz

0

post on the Boost mailing listに記載されているように、管理コードとアンマネージコードを別々の翻訳単位(.cppファイルと#includeヘッダー)に分割する方法があります。管理されていない翻訳単位からの参照のみをブーストします。管理対象の翻訳単位に対してのみ/ clrをオンにします。

0

あなたは、行を追加することができますget_static_exception_object宣言の前

#if _MANAGED 
#error "Don't include that file in CLI compilation units. It will cause failure when cleaning the static objects of the managed dll" 
#endif 

をし、あなたのCLIのファイルにのみ、そのファイル(またはそのファイルが含まれるブーストヘッダ)が含まれていません。

私の代わりに1つboost/thread.hppによってboost/thread/thread.hppは問題を修正しました。

関連する問題