【发布时间】:2012-03-15 12:47:04
【问题描述】:
这是一个致命错误,无法从中恢复,并且在发布版本中,会出现一个令人讨厌的消息框。当我调用 serial_port::cancel 并且 Boost 尝试抛出一些异常时会发生这种情况。确切的错误是:
运行时检查失败 #0 - ESP 的值未正确保存 通过函数调用。这通常是调用 用一个调用约定和一个函数指针声明的函数 使用不同的调用约定声明。
而且它似乎发生在 throw_error.ipp 中的 do_throw_error 方法中。 这是一个重现此内容的小示例程序:
#include <boost/asio/serial_port.hpp>
#include <boost/asio/read.hpp>
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
BYTE g_pBuffer[128];
void ReadCompletionHandler( boost::system::error_code ec, std::size_t bytesTransferred ){
if( !ec ){
cout << "Read " << bytesTransferred << " bytes successfully" << endl;
}else if( ec == boost::asio::error::operation_aborted ){
cout << "Aborted async_read_some, " << bytesTransferred << " bytes transferred" << endl;
}else{
cout << "Read finished with errors: " << ec.message() << endl;
}
}
void ReaderThread( boost::asio::serial_port* pSerialPort ){
cout << "[ReaderThread] Started reading" << endl;
boost::asio::async_read( *pSerialPort, boost::asio::buffer( g_pBuffer, 5 ), ReadCompletionHandler );
cout << "[ReaderThread] Done!" << endl;
}
void main(){
//Tell cout not to buffer its output so output better reflects multithreaded execution
std::cout.setf(std::ios::unitbuf);
boost::asio::io_service ioService;
boost::asio::serial_port serialPort( ioService );
string portName = "COM1";
serialPort.open( portName );
if( !serialPort.is_open() ){
cout << "Failed to open " << portName << endl;
return;
}
cout << "Launching reader thread and io_service" << endl;
boost::thread readerThread( boost::bind( ReaderThread, &serialPort ) );
ioService.run();
cout << "Sleeping..." << endl;
::Sleep( 5000 );
cout << "Woke up, cancelling pending reads" << endl;
serialPort.cancel();
cout << "Waiting for reader thread to finish..." << endl;
readerThread.join();
cout << "Done!" << endl;
cin.get();
}
也许我在做一些愚蠢的事情。你怎么看?
【问题讨论】:
-
AFAIK,完成处理程序需要 _stdcall 调用约定。
-
将 __stdcall 添加到
ReadCompletionHandler的定义并没有解决它。如果我将项目的调用约定更改为 __stdcall,它将停止构建。因此,Boost 似乎是使用 __cdecl 约定构建的。我应该重建 Boost 以便它使用 __stdcall 吗?
标签: c++ visual-studio-2010 serial-port boost-asio