c ++ boost asio асинхронные функции не будут работать внутри dll - PullRequest
3 голосов
/ 07 июня 2011

У меня есть этот простой код asio boost, основанный на руководстве, который отлично работает при вызове из exe, но вылетает при запуске из dll с использованием LoadLibrary. Он вылетает внутри буст-кода, а не моего кода. Он будет зависать в своих мьютекс-функциях потока 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-файла? Обратите внимание, что это происходит только при асинхронных вызовах. Синхронизация вызовов работает нормально

Спасибо

Ответы [ 2 ]

1 голос
/ 07 июня 2011

Некоторые библиотеки повышения (скомпилированные) используют глобальное состояние для внутреннего использования.Когда вы используете boost только из исполняемого файла, это не проблема, поскольку вы получаете только одну копию глобальных переменных.Когда вы загружаете библиотеку DLL, которая тоже использует boost, вы получаете еще одну копию глобального состояния, что приводит к непредсказуемому поведению.

Чтобы решить эту проблему, создайте динамическую ссылку для ускорения (скомпилируйте версии DLL и определите BOOST_ALL_DYN_LINK воба, DLL и EXE).Таким образом, вы получите только одну копию глобального состояния в памяти.

1 голос
/ 07 июня 2011

Типичной причиной сбоя в функциях DLL, которые работают в статически связанных библиотеках, является диспетчер памяти. DLL получит свою собственную копию диспетчера памяти, если вы не повсюду будете динамически связывать RTL. И поэтому каждый объект, пересекающий границу, должен быть уничтожен с помощью менеджера памяти, в котором он был создан, в противном случае уничтожение такого объекта приводит к сбою.

...