2011-11-15 73 views
8

我遇到了我創建的C++/CLI混合模式DLL的問題。它在卸載時拋出異常,因爲使用它的.NET應用程序退出。 DLL_PROCESS_DETACH被執行後,DLL確實運行清理使用自動註冊atexit()/__onexit()功能,並拋出以下異常:混合模式C++/CLI DLL在退出時拋出異常

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

我追蹤的問題是由一個靜態加速異常對象get_static_exception_object()註冊的atexit()通話。

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)* 

我使用boost_1_47靜態鏈接的大部分除了boost :: thread動態鏈接,以避免loaderlock。我也試着動態鏈接所有沒有幫助的提升。此外,所有的提升包括#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的標題)。僅從非託管翻譯單元中引用Boost。只爲受管翻譯單元開啓/ clr。 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文件的文件(或升壓報頭包括文件):

0

您可以添加行。

我替換一個boost/thread.hppboost/thread/thread.hpp修復了這個問題。