我有这个简单的提升基于教程的asio代码,从exe中调用时可以正常工作,但使用LoadLibrary从dll内运行时崩溃。 它在boost代码中崩溃而不是我的代码。 它会在90%的时间内在其线程互斥函数内部崩溃。 在执行dll代码时,是否有任何限制与exe相比?
这是我的代码:
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? 请注意,这只是asynchronous调用崩溃。 同步调用工作正常
谢谢
在静态链接库中工作的DLL函数崩溃的一个典型原因是内存管理器。 DLL将得到它自己的内存管理器的副本,除非你动态地链接RTL。 因此,每个穿过边界的物体都必须用它创建的内存管理器销毁,否则这种对象的破坏会导致崩溃。
一些boost库(被编译的)在内部使用全局状态。 如果仅从可执行文件使用boost,则不会出现问题,因为只获取全局变量的一个副本。 当你加载一个使用boost的DLL的时候,你会得到另一个全局状态的副本,这会导致不可预知的行为。
要解决这个问题,请动态链接(编译DLL版本并在DLL和EXE中定义BOOST_ALL_DYN_LINK)。 这样你只会在内存中获得全局状态的一个副本。