问题
Depending on how the socketio c++ library is compiled (static-lib or dll) for the following simple test code, the outcome is either a working executable or one that throws an exception.
However, if the instantiation of the io_service is commented out, eg.:
// boost::asio::io_service io_service;
then the static-lib based version is also working without exception. It seems that there is some interference between the io_service instantiated in main() with the io_service located in the socketIO library.
#define BOOST_ALL_NO_LIB
#include "../socketio/src/sio_client.h"
#include <boost\asio\io_service.hpp>
#include <memory>
#include <fstream>
#include <string>
#include <boost/lexical_cast.hpp>
int main(int argc, char* argv[]) {
boost::asio::io_service io_service;
//auto io_service_work = std::make_shared<boost::asio::io_service::work>(io_service);
sio::client client_;
client_.connect("http://localhost:1337");
//io_service.run();
}
Although the full source code is the same (not counting the optional conditional compilation differences), the evaluation of the following line results TRUE in the static-lib and FALSE in the Dll version:
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op))
Check the full code from win_iocp_io_service.ipp
void win_iocp_io_service::post_deferred_completion(win_iocp_operation* op)
{
// Flag the operation as ready.
op->ready_ = 1;
// Enqueue the operation on the I/O completion port.
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op)) // DIFFERENT RESULT IN STATIC-LIB AND DLL
{
// Out of resources. Put on completed queue instead.
mutex::scoped_lock lock(dispatch_mutex_);
completed_ops_.push(op);
::InterlockedExchange(&dispatch_required_, 1);
}
}
Please find a test package with two almost identical VS2015 solutions. Both solutions contain 2 projects (siotest and socketio). The package should be self-contained, so no additional libraries are needed to compile and test (thus the somewhat bigger size of the zip file).
Zip file containing the test package
Socketio is a library encompassing the open source c++11 socket.io client implementation from
Socket IO C++11 Client Implementation
Siotest is a simple test program, that would connect to a socketIO server.
Both Socketio and Siotest use boost asio ioservice, although the instantiated io_service variable in Siotest is not in use after the instantiation.
In the test case that was used for demonstrating the issue, there is no listening socketio server, so the expected behavior is Connection failed messages as shown in the following screenshot, because the client cannot connect to any server.
This output is the result of the siotest_dll solution, which is considered to be the expected behavior for the executable.
Another version of the solution in the siotest lib folder is almost entirely identical, but the linking of the socketio project is static library as opposed to dynamic linked library in the siotest dll.
The result of the erroneous socketio_lib run is shown in the screencap below
Debugging the two versions, it seems that when compiled in Dll mode, a new thread is created for socketio's internal io_service, but no new thread is created in the static lib version, because before creating the new thread, the static-lib version throws an exception.
There is clearly some difference between the two versions of the software, although the source code is exactly the same. The example is a simplification of our software framework in which we would like to use both the socket IO client C++ library and Boost Asio IO Service.
We would like to understand the source of the issue, and be able to compile our code as static library. Any advice is greatly appreciated.
来源:https://stackoverflow.com/questions/39772075/boost-asio-if-condition-evaluated-differently-in-static-lib-and-dll-compilations