2011-11-15 12 views
8

Mam problem z utworzoną przeze mnie biblioteką DLL trybu mieszanego C++/CLI. Wyrzuca wyjątek podczas rozładowywania, ponieważ aplikacja .NET, która używa go, kończy pracę. Po DLL_PROCESS_DETACH jest wykonywany, DLL robi Runtime clean-up przy użyciu automatycznie zarejestrowany atexit()/__onexit() funkcje i rzuca następujący wyjątek:Tryb mieszany C++/CLI DLL generuje wyjątek przy wyjściu

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

Mam prześledzić problem do atexit() rozmowy, który jest zarejestrowany przez impuls statyczny wyjątków obiektu get_static_exception_object() .

Używam boost_1_47 statycznie połączony w większości z wyjątkiem boost :: wątku, który jest dynamicznie połączony, aby uniknąć blokady ładowania. Próbowałem także dynamicznie łączyć wszystkie boosty, które nie pomogły. Także wszystkie elementy doładowania są otoczone blokami #pragma unmanaged.

Mam nadzieję, że ktoś miał podobny problem lub znał rozwiązanie?

Dzięki, Mark

Oto stos wywołań tuż przed występuje wyjątek:

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  

Odpowiedz

8

mam do czynienia ten sam problem i udało się go wyśledzić z następującą funkcją w 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; 
     } 

Problematyczna część tutaj jest: statyczny eksces ption_ptr ep (...

można po prostu usunąć statyczne i to powinno działać:

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; 
     } 

uwaga, jak ta funkcja jest używana, przypisuje zwrócony zmiennej statycznej do innej zmiennej statycznej. Cała implementacja tej funkcji wygląda podejrzanie, prawdopodobnie podniosę pytanie o wsparcie boost w tej sprawie.

Możliwe, że istnieją inne sposoby rozwiązania tego problemu. Więcej analiz dotyczących zmiennych statycznych w zespołach mieszanych można znaleźć tutaj: http://derevyanko.blogspot.com/2009/01/clic.html, jednak tylko w języku rosyjskim.

+0

DZIĘKUJEMY !!! Śledziłem to na zawsze. Nie znam C++ wystarczająco dobrze, aby zrozumieć, jak to powoduje wywołanie atexit. – pedz

0

Zgodnie z opisem w dokumencie post on the Boost mailing list, jednym podejściem jest rozdzielenie kodu zarządzanego i niezarządzanego na odrębne jednostki tłumaczeniowe (pliki .cpp i nagłówki, które one obejmują). Odwołaj się tylko do Boost z niezarządzanych jednostek tłumaczeniowych. Włącz tylko/clr dla zarządzanych jednostek tłumaczeniowych.

0

Możesz dodać linie:

#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 

przed get_static_exception_object deklaracji i nie obejmują tylko ten plik (lub jej nagłówek doładowania, które obejmują ten plik) w swoim CLI plików.

Dla mnie zastąpienie jednego boost/thread.hpp przez boost/thread/thread.hpp rozwiązało problem.

Powiązane problemy