简体   繁体   English

c++ boost asio 异步功能在 dll 内不起作用

[英]c++ boost asio asynchronous functions wont work inside dll

I have this simple boost asio code based on the tutorial which works fine when called from within an exe but crashes when ran from within a dll using LoadLibrary.我有这个基于教程的简单 boost asio 代码,当从 exe 中调用时工作正常,但在使用 LoadLibrary 从 dll 中运行时崩溃。 It crashes inside the boost code not my code.它在 boost 代码而不是我的代码中崩溃。 It will crash inside its thread mutex functions 90% of the time.它会在 90% 的时间内在其线程互斥函数内崩溃。 Is there any restrictions placed when executing code inside dll compared to an exe?与 exe 相比,在 dll 中执行代码时是否有任何限制?

This is my code:这是我的代码:

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
}

Is there any reason why this code would crash inside a dll and not an exe?是否有任何原因导致此代码会在 dll 而不是 exe 中崩溃? Please note it is only the async calls that crash.请注意,只有异步调用会崩溃。 The sync calls work fine同步调用工作正常

Thanks谢谢

A typical reason for crashing in DLL functions that work in statically linked libraries is memory manager.在静态链接库中工作的 DLL 函数崩溃的一个典型原因是 memory 管理器。 DLL will get it's own copy of memory manager, unless you link RTL dynamically everywhere. DLL 将获得它自己的 memory 管理器副本,除非您在任何地方动态链接 RTL。 And therefore every object crossing the boundary must be destroyed with the memory manager it was created, otherwise destruction of such object results in crash.因此,每个跨越边界的 object 都必须使用创建的 memory 管理器销毁,否则销毁此类 object 会导致崩溃。

Some boost libraries (those that are compiled) use global state internally.一些 boost 库(那些已编译的)在内部使用全局 state。 When you use boost from your executable only, it is not a problem since you get just one copy of the globals.当您仅从可执行文件中使用 boost 时,这不是问题,因为您只获得了一份全局变量的副本。 When you load a DLL that uses boost too, you get yet another copy of the global state, which leads to unpredictable behavior.当你加载一个也使用 boost 的 DLL 时,你会得到另一个全局 state 的副本,这会导致不可预知的行为。

To solve the problem, link to boost dynamically (compile the DLL versions and define BOOST_ALL_DYN_LINK in both, DLL and EXE).为了解决这个问题,链接到动态提升(编译 DLL 版本并在 DLL 和 EXE 中定义 BOOST_ALL_DYN_LINK)。 This way you'll get only one copy of global state in memory.这样,您将在 memory 中仅获得一份全局 state 副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM