2011-06-07 49 views
3

我有這個簡單的基於教程的asio代碼,它在EXE中調用時工作正常,但是在使用LoadLibrary從dll內運行時崩潰。它在boost代碼中崩潰而不是我的代碼。 90%的時間內它會在其線程互斥功能內部崩潰。在執行dll內部的代碼時,是否存在與exe相比的任何限制?C++ boost asio異步函數不會在DLL內工作

這是我的代碼:

Connection::Connection(boost::asio::io_service& ioservice) 
    : m_Socket(ioservice) 
    , m_Resolver(ioservice) 
{ 
} 

void Connection::ConnectTo() 
{ 
    boost::asio::ip::tcp::resolver::query query("www.google.com", "http"); 
    boost::asio::ip::tcp::resolver::iterator iterator = m_Resolver.resolve(query); 
    boost::asio::ip::tcp::endpoint endpoint = *iterator; 

    // crashes here inside async_connect    
    m_Socket.async_connect(endpoint, 
     boost::bind(&Connection::HandleConnect, shared_from_this(), 
     boost::asio::placeholders::error, ++iterator)); 

} 

void Connection::HandleConnect(const boost::system::error_code& e, 
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator) 
{ 
    // never reaches here 
} 

沒有任何理由爲什麼這個代碼會崩潰一個dll,而不是一個exe裏面?請注意,這只是異步調用崩潰。同步調用做工精細

感謝

+0

你鏈接靜態或動態提升? – ybungalobill 2011-06-07 06:54:32

+0

您是否在DLL中使用C++或C接口導出函數? – 2011-06-07 06:57:28

+0

動態。謝謝 – Clive 2011-06-07 06:58:03

回答

1

在單位工作的靜態鏈接庫DLL功能崩潰的常見原因是內存管理器。 DLL將獲得它自己的內存管理器副本,除非您在任何地方動態鏈接RTL。因此,每個穿越邊界的物體都必須使用它創建的內存管理器來銷燬,否則這種對象的破壞會導致崩潰。

+0

我試着對dll版本的boost進行重建,並定義了BOOST_ALL_DYN_LINK,並得到了同樣的崩潰。 – Clive 2011-06-07 07:46:52

+0

問題是DLL和可執行文件是否都是動態鏈接的(我假設是VC)RTL。 – 2011-06-07 18:41:05

+0

是的exe和DLL都是動態鏈接在VC使用/ MDd – Clive 2011-06-09 06:40:01

1

一些boost庫(編譯的庫)在內部使用全局狀態。如果僅從可執行文件使用boost,則不會出現問題,因爲您僅獲取全局變量的一個副本。當你加載一個使用boost的DLL時,你會得到全局狀態的另一個副本,這會導致不可預知的行爲。

要解決此問題,請動態鏈接以提升(編譯DLL版本並在DLL和EXE中同時定義BOOST_ALL_DYN_LINK)。這樣你就只能在內存中獲得全局狀態的一個副本。

+0

但這是否意味着當我運送我的EXE我需要發送升壓DLL文件?謝謝。 – Clive 2011-06-07 07:12:41

+0

我試着對dll版本的boost進行重建,並定義了BOOST_ALL_DYN_LINK,並得到了相同的崩潰。 – Clive 2011-06-07 07:46:15