前言:
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. 編寫如下代碼進行編譯/運行認證
1 #include <iostream> 2 #include <string> 3 #include <boost/regex.hpp> 4 int main() 5 { 6 boost::regex pattern("\\w+@\\w+(\\.\\w+)*"); 7 std::string mail("xxx@gmail.com"); 8 9 if ( boost::regex_match(mail, pattern) ) { 10 std::cout << mail << " is a valid mail address!" << std::endl; 11 } else { 12 std::cout << mail << " is not a valid mail address!" << std::endl; 13 } 14 }
安裝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添加如下行:
1 #ifdef WIN32 2 #include <winsock2.h> 3 #include <ws2tcpip.h> 4 #pragma comment(lib,"ws2_32.lib") 5 #define WIN32_LEAN_AND_MEAN 6 #include <windows.h> 7 #undef WIN32_LEAN_AND_MEAN 8 #include <io.h> 9 #include <tchar.h> 10 #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"
|
1 #include <event.h> 2 #include <stdio.h> 3 4 int main() 5 { 6 const char *version = event_get_version(); 7 printf("%s\n",version); 8 return 0; 9 }
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的調用采用全局聲明的那個函數
1 assert.h 2 3 #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) ) 4 5 #define assert(_Expression) (void)( (!!(_Expression)) || (::_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) ) 6
1 namespace cpp test 2 3 service HelloService { 4 string hello(1: string username); 5 }
1 2014/05/07 11:35 9,215 HelloService.cpp 2 2014/05/07 11:26 7,117 HelloService.h 3 2014/05/07 11:26 1,422 HelloService_server.skeleton.cpp 4 2014/05/07 11:35 268 hello_constants.cpp 5 2014/05/07 11:35 357 hello_constants.h 6 2014/05/07 11:35 202 hello_types.cpp 7 2014/05/07 11:35 367 hello_types.h
1 class HelloServiceHandler : virtual public HelloServiceIf { 2 public: 3 HelloServiceHandler() { 4 // Your initialization goes here 5 } 6 7 void hello(std::string& _return, const std::string& username) { 8 _return = "hello " + username; 9 } 10 11 }; 12 13 int main(int argc, char **argv) { 14 int port = 9090; 15 16 TWinsockSingleton::create(); // 需要用戶自己添加, 進行WSAStartup的初始化, 算是windows 版的thrift的一個疏忽 17 18 shared_ptr<HelloServiceHandler> handler(new HelloServiceHandler()); 19 shared_ptr<TProcessor> processor(new HelloServiceProcessor(handler)); 20 shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); 21 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); 22 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); 23 24 TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); 25 server.serve(); 26 return 0; 27 }
1 2 #include "HelloService.h" 3 #include <thrift/protocol/TBinaryProtocol.h> 4 #include <thrift/server/TSimpleServer.h> 5 #include <thrift/transport/TBufferTransports.h> 6 #include <thrift/transport/TSocket.h> 7 8 using namespace ::apache::thrift; 9 using namespace ::apache::thrift::protocol; 10 using namespace ::apache::thrift::transport; 11 using namespace ::apache::thrift::server; 12 13 using boost::shared_ptr; 14 15 using namespace ::test; 16 17 int main() 18 { 19 20 shared_ptr<TTransport> socket(new TSocket("127.0.0.1", 9090)); 21 shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 22 shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 23 24 HelloServiceClient client(protocol); 25 26 try { 27 transport->open(); 28 std::string res; 29 client.hello(res, "lilei"); 30 std::cout << res << std::endl; 31 } catch(TException &e) { 32 std::cout << e.what() << std::endl; 33 } 34 35 return 0; 36 } 37

