最近在做视频产品的开发,在网络交互上选择的是boost的asio库,由于boost没有提供数据库访问的库,所以采用了Poco库,但是在项目中同时使用这两个库--Poco库引入PocoDataMySQL的头文件Poco/Data/MySQL/MySQLConnect.h,boost库调用了tcp::acceptor的async_accpet方法时,程序报“用户回调期间未处理异常”异常,报错位置在PocoMySQLConnect文件的mysql_library_init方法里面,错误如下图:
解决方法是,在自己定义的数据库访问的类的头文件中加入:
#define POCO_NO_UNWINDOWS
该宏定义,同时还需调整lib库的引入顺序,PocoDataMySQL.lib库必须放在最后
下面是简单的示例说明:
DBClient.h头文件
#pragma once
#define POCO_NO_UNWINDOWS
#include "Poco/Exception.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/SessionPool.h"
#include "typehandler/VrmRecordSchedulerTypeHandler.h"
#include "typehandler/VrmScheduleTemplTypeHandler.h"
#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/SQLite/Connector.h"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <string>
#include <list>
#include "tool/DBConfig.h"
#include "Poco/LocalDateTime.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeParser.h"
#include "info/ScheduleInfo.h"
#include "db/model/VrmScheduleTemplModel.h"
namespace innovss
{
class DBClient
{
public:
DBClient();
virtual ~DBClient();
public:
bool searchVrmRecordSheduleTempl();
bool searchVrmRecordSchedule();
private:
void registerDBSession();
void unRegisterDBSession();
void calcRecordStartEndTime(VrmScheduleTemplModel &it,ScheduleInfo &info);
void calcRecordStartEndTime(std::string templStr,DayScheduleInfo &info,INT32 scheduleTemplId);
void searchVrmRecordSchedule(ScheduleInfo &info);
private:
DBConfig dbConfig;
Poco::Data::SessionPool sessionPool;
bool isSessionReg;
bool isFirstSearchDB;
Poco::LocalDateTime lastSearchTime;
public:
std::map<int,ScheduleInfo> scheduleInfoList;
};
}
Main.cpp文件
// DataBaseTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "db/DBClient.h"
#include "Util/Thread.h"
#include "Util/TiXml.h"
#include <WinSock2.h>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::asio::ip::udp;
using boost::asio::ip::tcp;
using boost::asio::ip::address;
using namespace boost::asio;
#define max_len 1024
class clientSession
:public boost::enable_shared_from_this<clientSession>
{
public:
clientSession(boost::asio::io_service& ioservice)
:m_socket(ioservice)
{
memset(data_,'\0',sizeof(data_));
}
~clientSession()
{}
tcp::socket& socket()
{
return m_socket;
}
void start()
{
boost::asio::async_write(m_socket,
boost::asio::buffer("link successed!"),
boost::bind(&clientSession::handle_write,shared_from_this(),
boost::asio::placeholders::error));
m_socket.async_read_some(boost::asio::buffer(data_,max_len),
boost::bind(&clientSession::handle_read,shared_from_this(),
boost::asio::placeholders::error));
}
private:
void handle_write(const boost::system::error_code& error)
{
if(error)
{
m_socket.close();
}
}
void handle_read(const boost::system::error_code& error)
{
if(!error)
{
std::cout << data_ << std::endl;
m_socket.async_read_some(boost::asio::buffer(data_,max_len),
boost::bind(&clientSession::handle_read,shared_from_this(),
boost::asio::placeholders::error));
}
else
{
m_socket.close();
}
}
private:
tcp::socket m_socket;
char data_[max_len];
};
typedef boost::shared_ptr<clientSession> session_ptr;
void handle_accept(const boost::system::error_code& error,session_ptr& session)
{
}
class test
{
public:
test(){
}
void init()
{ short port = 8100/*argv[1]*/;
boost::asio::io_service ioservice;
boost::asio::io_service& m_ioservice(ioservice);
tcp::endpoint endPoint(tcp::v4(),port);
session_ptr new_session(new clientSession(ioservice));
tcp::acceptor acceptor_(ioservice,endPoint);
acceptor_.async_accept(new_session->socket(),
boost::bind(&test::handle_accept_xxx_1_3,
this,boost::asio::placeholders::error,
new_session));
}
void handle_accept_xxx_1_3(const boost::system::error_code& error,session_ptr& session)
{
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int i;
innovss::DBClient dbClient;
dbClient.searchVrmRecordSheduleTempl();
test testt;
testt.init();
std::cin>>i;
return 0;
}
注:#define Poco_NO_UNWINDOWS宏定义用于解决Poco与boost的编译错误问题,不加该宏定义会报如下错误:
error C2039: “CreateEvent”:is not “`global namespace'” member. .\boost_1_43_0\boost\asio\detail\win_iocp_handle_service.hpp 261
error C3861: “CreateEvent”: unresolve......\boost\boost_1_43_0\boost\asio\detail\win_iocp_handle_service.hpp 261
如果添加代码后还报如下错误的话
error 4 fatal error C1189: #error : WinSock.h has already been included ..\boost\boost_1_43_0\boost\asio\detail\socket_types.hpp 27
则需要加入 #define WIN32_LEAN_AND_MEAN 这个宏定义