1. 程式人生 > >windows下如何使用thrift,及編譯執行的全過程。boost庫的使用,libevent 庫的使用

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中輸入,是輸入不進去的,看清了,要在客戶端的輸入啊!!)