前言:
thrift是出于Facebook的rpc网络编程框架, 其对跨平台和多语言的支持优于google protobuf, 但thrift在java/c#语言上应用比较多, 资料也丰富, 在windows平台的c++这块, 资料相对较少, 而且编译也麻烦. 这篇博客主要记录对thrift在windows上的编译和使用过程, 不涉及原理, 也不具体涉及应用.如有不足, 请各位指正.
执行过程
1. 下载并安装Visual Studio
notice: visual studio 有windows版本限制, 比如visual studio 2013在windows 7就安装不了
参考网址: http://www.visualstudio.com/zh-cn/visual-studio-2013-compatibility-vs
系统: windows7 + visual studio 2012
2. boost安装/编译/链接
具体步骤如下:
*) 下载boost
1. 下载 boost_1_55_0.zip
*) 编译boost
1. 执行 bootstrap.bat
2. 执行 b2.exe (编译的时间较长, 请耐心等待)
*) 验证boost
在virtual studio的window console工程属性中添加如下:
1. 附加包含目录: $BOOST_HOME
2. 附加库目录: $BOOST_HOME\stage\lib
3. 编写如下代码进行编译/运行认证
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main()
{
boost::regex pattern("\\w+@\\w+(\\.\\w+)*");
std::string mail("xxx@gmail.com"); if ( boost::regex_match(mail, pattern) ) {
std::cout << mail << " is a valid mail address!" << std::endl;
} else {
std::cout << mail << " is not a valid mail address!" << std::endl;
}
}
安装boost和配置visual studio的参考网址如下所示:
http://blog.csdn.net/stanfordzhang/article/details/8587282
http://www.cnblogs.com/me115/archive/2010/10/08/1845825.html
http://www.cnblogs.com/chuncn/archive/2012/09/10/2679026.html
3. libevent的编译/安装/链接
*) 参考的编译/安装过程网页
http://blog.s135.com/libevent_windows/
*) 下载libevent
http://libevent.org/
*) 编译libevent
遇到的编译错误处理方案
http://10305101ivy.blog.163.com/blog/static/584765892012227322607/
http://blog.csdn.net/boyxiaolong/article/details/17057063
evutil.c添加如下行:
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <io.h>
#include <tchar.h>
#endif
nmake /f Makefile.nmake
生成libevent_core.lib libevent_extras.lib libevent.lib
若遇到头文件找不到的问题, 需要手动修改Makefile.nmake文件, 添加相关的头文件路径
CFLAGS=/IWIN32-Code /Iinclude /Icompat /DWIN32 /DHAVE_CONFIG_H /I. /I"C:\Program Files (x86)\Windows Kits\8.0\Include\um" /I"C:\Program Files (x86)\Windows Kits\8.0\Include\shared" /I"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include"
|
#include <event.h>
#include <stdio.h> int main()
{
const char *version = event_get_version();
printf("%s\n",version);
return ;
}
4. thrift的编译/链接
*)下载thrift 0.9.0源码
下载网址: http://archive.apache.org/dist/thrift
*)thrift依赖的库
http://www.coder4.com/archives/3777
thrift 依赖 boost库(1.4.7), thriftnb 依赖 boost/libevent库
http://www.iteye.com/problems/87958
thrift在编译过程中, 会遇到二义性
“_wassert”: 对重载函数的调用不明确
void _wassert(const wchar_t *,const wchar_t *,unsigned int)
void apache::thrift::protocol::_wassert(const wchar_t *,const wchar_t *,unsigned int)
解决方案:
这算命令空间污染的问题, 添加::, 使得对_wassert的调用采用全局声明的那个函数
assert.h #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) ) #define assert(_Expression) (void)( (!!(_Expression)) || (::_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
namespace cpp test service HelloService {
string hello(: string username);
}
// : , HelloService.cpp
// : , HelloService.h
// : , HelloService_server.skeleton.cpp
// : hello_constants.cpp
// : hello_constants.h
// : hello_types.cpp
// : hello_types.h
class HelloServiceHandler : virtual public HelloServiceIf {
public:
HelloServiceHandler() {
// Your initialization goes here
} void hello(std::string& _return, const std::string& username) {
_return = "hello " + username;
} }; int main(int argc, char **argv) {
int port = ; TWinsockSingleton::create(); // 需要用户自己添加, 进行WSAStartup的初始化, 算是windows 版的thrift的一个疏忽 shared_ptr<HelloServiceHandler> handler(new HelloServiceHandler());
shared_ptr<TProcessor> processor(new HelloServiceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return ;
}
#include "HelloService.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TSocket.h> using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server; using boost::shared_ptr; using namespace ::test; int main()
{ shared_ptr<TTransport> socket(new TSocket("127.0.0.1", ));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); HelloServiceClient client(protocol); try {
transport->open();
std::string res;
client.hello(res, "lilei");
std::cout << res << std::endl;
} catch(TException &e) {
std::cout << e.what() << std::endl;
} return ;
}