2011-11-15 27 views
8

Tôi gặp sự cố với DLL chế độ hỗn hợp C++/CLI mà tôi đã tạo. Nó là một ngoại lệ khi dỡ bỏ như ứng dụng .NET sử dụng nó thoát. Sau DLL_PROCESS_DETACH được thực thi, các DLL không runtime sạch-up sử dụng tự động đăng ký atexit()/__onexit() chức năng và ném ngoại lệ sau đây:Chế độ hỗn hợp C++/CLI DLL ném ngoại lệ khi thoát

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

Tôi đã bắt nguồn từ các vấn đề để một atexit() cuộc gọi mà được đăng ký bởi một sự thúc đẩy tĩnh ngoại lệ đối tượng get_static_exception_object() .

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

Tôi đang sử dụng boost_1_47 liên kết tĩnh cho hầu hết các phần ngoại trừ tăng :: chuỗi được liên kết động để tránh loaderlock. Tôi cũng đã cố gắng tự động liên kết tất cả các tăng mà không giúp đỡ. Ngoài ra tất cả các tăng bao gồm được bao quanh bởi #pragma unmanaged khối.

Tôi hy vọng ai đó đã gặp sự cố tương tự hoặc biết giải pháp?

Cảm ơn, Mark

Dưới đây là các cuộc gọi stack ngay trước khi ngoại lệ xảy ra:

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  

Trả lời

8

tôi đã phải đối mặt với cùng một vấn đề và quản lý để theo dõi nó xuống để các chức năng sau đây trong 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; 
     } 

Phần có vấn đề ở đây là: tĩnh exce ption_ptr ep (...

Bạn chỉ có thể loại bỏ tĩnh và cần làm việc:

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

Lưu ý cách chức năng này được sử dụng, nó gán trở lại biến tĩnh để một biến tĩnh. Việc thực hiện toàn bộ chức năng này có vẻ đáng ngờ, có lẽ tôi sẽ nêu ra một câu hỏi về hỗ trợ tăng cường về điều này.

Có thể có các cách giải quyết khác để khắc phục sự cố này. Phân tích thêm về các biến tĩnh trong các cụm hỗn hợp có thể được tìm thấy ở đây: http://derevyanko.blogspot.com/2009/01/clic.html tuy nhiên chỉ bằng tiếng Nga.

+0

CẢM ƠN BẠN !!! Tôi đã theo dõi điều này mãi mãi. Tôi không biết C++ cũng đủ để hiểu làm thế nào mà gây ra một cuộc gọi để atexit. – pedz

0

Như được mô tả trong một post on the Boost mailing list, một cách tiếp cận là tách mã được quản lý và không được quản lý thành các đơn vị dịch riêng biệt (tệp .cpp và tiêu đề chúng #include). Chỉ tham chiếu Boost từ các đơn vị dịch không được quản lý. Chỉ bật/clr cho các đơn vị dịch được quản lý.

0

Bạn có thể thêm các dòng:

#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 

trước khi khai get_static_exception_object và không bao gồm duy nhất mà tập tin (hoặc một tiêu đề tăng trong đó bao gồm tập tin đó) trong các tập tin cli của bạn.

Để tôi thay thế một boost/thread.hpp bằng cách boost/thread/thread.hpp khắc phục sự cố.

Các vấn đề liên quan