2011-06-07 48 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