当我在 iOS 平台上使用 boost.asio、boost.thread 等时,应用程序在 int 发布模式下崩溃,但在 int 调试模式下运行良好。正如我在此描述的那样,我修复了发布运行时错误。
我的问题是:为什么在调试模式下一切正常?答案似乎是说崩溃是由拇指标志引起的。调试模式编译器应该使用与发布模式相同的“拇指”标志,我想知道应用程序也应该因为使用拇指而在调试模式下崩溃,这让我感到困惑。
更新: 这是我使用 asio 的代码:
参数被声明为 CrossPlatformAPI 的私有成员:
boost::recursive_mutex m_mutex;
boost::asio::io_service m_ioService;
boost::scoped_ptr<boost::asio::io_service::work> m_idleWork;
boost::scoped_ptr<boost::thread> m_mainThread;
首先,我通过在主线程中调用 CrossPlatformAPI::Init 来发布两个异步任务:
int CrossPlatformAPI::Init(const P2PInitParam& oInitParam)
{
boost::recursive_mutex::scoped_lock lock(m_mutex);
m_idleWork.reset(new boost::asio::io_service::work(m_ioService));
m_mainThread.reset(new boost::thread(boost::bind( &boost::asio::io_service::run, &m_ioService)));
std::string strLog(oInitParam.szAppDataDir);
m_ioService.post(boost::bind( &CrossPlatformAPI::HandleLog, this, strLog));
m_ioService.post(boost::bind( &CrossPlatformAPI::HandleInit, this, oInitParam));
return 0;
}
其次,CrossPlatformAPI::HandleLog 和 CrossPlatformAPI::HandleInit 处理异步任务:
void CrossPlatformAPI::HandleLog(std::string & log)
{
std::cout << log << std::endl;
}
void CrossPlatformAPI::HandleInit(P2PInitParam& oInitParam)
{
try
{
//Init
//...
}
catch (std::exception&)
{
}
return;
}
我尝试使用 boost:ref 包装绑定参数而不是直接绑定,然后应用程序不会崩溃。为什么不?还有让我感到困惑的是,如果绑定参数类型是std::string,那么当被std::ref 包裹时,handle 函数接收到的参数是不正确的。似乎 std::string 不使用 std::ref 效果很好:没有崩溃并且接收的值是正确的,但不是 sruct-type 参数,如 P2PInitParam。
更新2:
int CrossPlatformAPI::Init(const P2PInitParam& oInitParam)
{
boost::recursive_mutex::scoped_lock lock(m_mutex);
m_idleWork.reset(new boost::asio::io_service::work(m_ioService));
m_mainThread.reset(new boost::thread(boost::bind( &boost::asio::io_service::run, &m_ioService)));
std::string strLog(oInitParam.szAppDataDir);
m_ioService.post(boost::bind( &CrossPlatformAPI::HandleLog, this, boost::cref(strLog))); // OK
m_ioService.post(boost::bind( &CrossPlatformAPI::HandleInit, this, boost::cref(oInitParam))); // Crash
return 0;
}
void CrossPlatformAPI::HandleLog(const std::string& log)
{
std::cout << log << std::endl;
}
void CrossPlatformAPI::HandleInit(const P2PInitParam& oInitParam)
{
try
{
//Init
//...
}
catch (std::exception&)
{
}
return;
}