windows下如何使用thrift,及編譯執行的全過程。boost庫的使用,libevent 庫的使用
1、thrift的版本很多,目前截止貼主發帖時間:最新的為thrift-0.9.2。但是經過多次嘗試:在vs2012中好像有一次編譯成功,vs2010和vs2013都出現編譯錯誤,錯誤如下:
F:\thritfLib\thriftOkLib\openssl\openssl-1.0.2d\include\openssl/err.h(1): error C2059: 語法錯誤:“.”
2>F:\thritfLib\thriftOkLib\thrift\thrift-0.9.2\lib\cpp\src\thrift/concurrency/Mutex.h(26): error C2143: 語法錯誤 : 缺少“;”(在“{”的前面)
2>F:\thritfLib\thriftOkLib\thrift\thrift-0.9.2\lib\cpp\src\thrift/concurrency/Mutex.h(26): error C2447: “{”: 缺少函式標題(是否是老式的形式表?)
2>F:\thritfLib\thriftOkLib\openssl\openssl-1.0.2d\include\openssl/ssl.h(1): error C2059: 語法錯誤:“.”
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\xtree(15): error C2143: 語法錯誤 : 缺少“;”(在“{”的前面)
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\xtree(15): error C2447: “{”: 缺少函式標題(是否是老式的形式表?)
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(69): error C2143: 語法錯誤 : 缺少“,”(在“<”的前面)
2> D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(256): 參見對正在編譯的類 模板 例項化“std::map<_Kty,_Ty,_Pr,_Alloc>”的引用
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(73): error C2143: 語法錯誤 : 缺少“;”(在“<”的前面)
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(73): error C4430: 缺少型別說明符 - 假定為 int。注意: C++ 不支援預設 int
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(73): error C2238: 意外的標記位於“;”之前
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(78): error C2653: “_Mybase”: 不是類或名稱空間名稱
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(78): error C2146: 語法錯誤: 缺少“;”(在識別符號“value_compare”的前面)
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(78): error C4430: 缺少型別說明符 - 假定為 int。注意: C++ 不支援預設 int
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(78): error C2868: “std::map<_Kty,_Ty,_Pr,_Alloc>::value_compare”: 非法的 using 宣告語法;應輸入限定名
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(79): error C2653: “_Mybase”: 不是類或名稱空間名稱
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(79): error C2146: 語法錯誤: 缺少“;”(在識別符號“allocator_type”的前面)
2>D:\Program Files\Microsoft Visual Studio 12.0\VC\include\map(79): error C4430: 缺少型別說明符 - 假定為 int。注意: C++ 不支援預設 int
、、、、、、、、、、、、、、、、、、、、、、、、、、、
由於自己的能力還不夠,目前無法解決這個問題,如有大神知道怎麼解決麻煩指點呢!!!!
、、、、、、、、、、、、
前提:我用的是vs2013 + thrift-0.9.0 + libevent-.2.0.22-stable + boost_1_58_0 + openssl-1.0.1p
關於boost 。libevent. openssl 編譯和使用可參考如下:這部分主要參考:
http://www.tuicool.com/articles/iyquIz
@ boost安裝/編譯/連結
具體步驟如下:
*) 下載boost
1. 下載 boost_1_58_0.zip
*) 編譯boost
1. 執行 bootstrap.bat
2. 執行 b2.exe (編譯的時間較長, 請耐心等待)
*) 驗證boost
在virtual studio的window console工程屬性中新增如下:
1. 附加包含目錄: F:\thritfLib\LibAll\boost\boost_1_58_0
2. 附加庫目錄: F:\thritfLib\LibAll\boost\boost_1_58_0\stage\lib
3. 編寫如下程式碼進行編譯/執行認證
1 #include <iostream>
2 #include <string>
3 #include <boost/regex.hpp>
4 int main()
5 {
6 boost::regex pattern("\\[email protected]\\w+(\\.\\w+)*");
7 std::string mail("[email protected]");
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 }
@libevent的編譯/安裝/連結
*) 參考的編譯/安裝過程網頁
http://blog.s135.com/libevent_windows/
*) 下載libevent
http://libevent.org/
*) 編譯libevent
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
編寫libevent程式碼編譯/執行成功
1. 附加包含目錄: F:\thritfLib\LibAll\libEvent\libevent-2.0.22-stable\include(注意將:..\libevent-2.0.22-stable\WIN32-Code\event2下面的event-config.h也拷貝到..\libevent-2.0.22-stable\include中)
2.
附加庫目錄: F:\thritfLib\LibAll\libEvent\libevent-2.0.22-stable
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 }//宣告:上面的編譯是個人蔘考後修改和總結。具體屬其博主。
關於thrfit的使用問題如下:
最好將boost 的include,lib 和libevent 的include 和lib,openssl的include,歸檔整理放好使用。
1、vs建win32控制檯應用程式
在該工程下預設的是server專案,然後再改解決方案下再新增一個專案,方法是:右鍵點選解決方案-->新增---->新建專案。該專案定位client客戶端專案
2、編寫Hello.thrift檔案(用文字.txt寫就可以)
namespace cpp test
service HelloService {
string hello(1: string username);
}
3、將thrift-0.9.0.exe 下載後拷貝到與Hello.thrfit檔案同一個資料夾下面。然後開啟“VS2013 x86 本機工具命令提示”
第一步: d: 第二步:cd “到Hello.thrift 檔案”, 第三步:thrift-0.9.0.exe -gen cpp Hello.thrift
4。此時生產一個gen-cpp資料夾,裡面有7個檔案,如下所示:圖0
Hello_constants.cpp、Hello_constants.h、Hello_types.cpp、Hello_types.h、HelloService.cpp、HelloService.h、HelloService_server.skeleton.cpp
5、將這幾個檔案都拷貝到上面建的server和client工程專案資料夾下,該資料夾在後期編譯的時候會生產debug或release資料夾,如過不是同一目錄,那說明放置有問題。
6、在vs中分別新增這幾個檔案到server和client的工程專案中。我的新增時如下形式:圖1
server中7個檔案都要。其中client專案不需要新增HelloService_server.skeleton.cpp檔案,換成新增一個空白的client.cpp檔案
在client.cpp檔案中新增的程式碼如下:圖2
#include "HelloService.h"
#include <transport/TSocket.h>
#include <transport/TBufferTransports.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
using namespace std;
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(int argc, char **argv) {
boost::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "wsaData error!" << endl;
}
//
HelloServiceClient helloClient(protocol);
try
{
transport->open();
// 我們的程式碼寫在這裡
string res;
string inString;
cin >> inString;
helloClient.hello(res, "hello world ,This is my first thrift !");
cout << inString << endl;
transport->close();
}
catch (TException &e)
{
cout << e.what() << endl;
}
return 0;
}
如過你的有問題,不防一個一個對對,看少了什麼。
此外,在HelloService_server.skeleton.cpp檔案中需要注意的是;需要修改一個地方:
在main函式中新增一個語句:
TWinsockSingleton::create();
放在int port = 9090;之後便可以了。不然有問題。
另外在hello的方法中(位於HelloServiceHandler類中),printf可修改成這樣:
printf("hello + %s.", username.c_str()); 便可以列印client客戶端傳入"hello world ,This is my first thrift !"了。
7、最後就是include,lib庫的問題了
我的如下:
@1: server的專案屬性中 找到c/c++常規->附加包含目錄分別指定:
boost\include,thrift-0.9.0\lib\cpp\src\thrift 和thrift-0.9.0\lib\cpp\src 字首是你的專案中這些東西的具體位置;
找到:連結器->常規->附加庫目錄;新增如下
boost\lib,thrift-0.9.0\lib\cpp\debug(或者release,要看你用的是哪個) 和libevent\lib 字首是你的專案中這些東西的具體位置
找到:連結器->輸入->附加依賴項:新增:libthrift.lib
@2:client的專案屬性中 找到c/c++常規->附加包含目錄分別指定:
boost\include,thrift-0.9.0\lib\cpp\src\thrift 和thrift-0.9.0\lib\cpp\src 字首是你的專案中這些東西的具體位置;
找到:連結器->常規->附加庫目錄;新增如下
boost\lib,thrift-0.9.0\lib\cpp\debug(或者release,要看你用的是哪個) 和libevent\lib 字首是你的專案中這些東西的具體位置
找到:連結器->輸入->附加依賴項:新增:libthrift.lib
最後關於:include 可能有些不需要,這個自己再測試,如果按照上面的步驟操作,thrift,應該沒問題。
編譯執行的時候,要設定server先啟動,client後啟動,在解決方案中可以這樣設定:
還是通過右鍵點選找到:設定啟動專案,然後按照上圖所示修改。上面是server
總結:
關於最後include只需要:
thrift-0.9.0\lib\cpp\src\thrift 和thrift-0.9.0\lib\cpp\src
lib:需要thrift-0.9.0\lib\cpp\debug 和boost\lib,如果有問題,再新增libevent的庫路徑
到此,就可以沒問題了測試展示:圖3
客戶端需要輸入字元,隨便輸入,便可以(server中輸入,是輸入不進去的,看清了,要在客戶端的輸入啊!!)