Thrift windows下cpp编译与使用

来源:互联网 发布:预算软件有哪些 编辑:程序博客网 时间:2024/06/01 07:56

本文主要目的是分别介绍在Windows平台下的Thrift安装步骤,以及实现一个简单的demo演示Thrift的使用方法。

Thrift下载

官网下载源码     Thrift代码生成器工具下载
安装依赖库:

  1. boost
  2. openssl(windows下有编译好的二进制文件,可以直接下载 windows版openssl )
  3. libevent(按需安装,实例中我没有使用)

Thrift在windows下编译

所用机子:windows10,64位
编译环境:VS2015
首先这里介绍0.10.0和0.9.3两个版本
一开始,我是下载了0.10.0版本和对应的代码生成工具,但是后面在做实例的时候发现0.10.0版本的代码生成工具在我本机无法启动,提示版本不合适,为了后面使用一致性,我下载了0.9.3版本进行使用。

0.10.0版本的cpp编译比较容易成功,编译64位版本的libthrift.lib,打开thrift-0.10.0\lib\cpp\thrift.sln,里面有libthrift和libthriftnb两个工程,其中libthrift工程是常规的阻塞型server端(单线程server,一个连接一个线程server,线程池server),libthriftnb工程是非阻塞(non-blocking)模式的服务server端,也只有编译libthriftnb时才需要依赖libevent库,否则可以不编译libevent库;编译libthrift只要把正确的boost路径和openssl路径配置正确,就可以编译成功了。

0.9.3版本的cpp编译,官网上提供的sln打开后编译是编不过的,工程有很多需要修改的地方,首先,boost和openssl包含路径和库路径配置正确后,观察libthrift工程里面的文件,对比源码目录,有很多缺少的文件,首先,Thrift.cpp已经不存在,把它从项目中手动移除,再把thrift文件夹内TDispatchProcessor.h、thrift-config.h、TLogging.h、TOutput.cpp、TOutput.h、TProcess.h、TToString.h、VirtualProfiling.cpp包含进工程中,整理OverlappedSubmissionThread.cpp和OverlappedSubmissionThread.h进windows筛选器,分别打开thrift\windows,thrift\async,thrift\concurrency,thrift\processor,thrift\protocol,thrift\server,thrift\transport,与源码目录对比,添加缺少目录:
windows目录 server目录 async目录 protocol目录 concurrency&processor目录 transport目录
说明:已移除部分不适用与windows平台的文件
在编译时还有部分文件出错:TServerFramework.cpp #222 移除std::
(transport\TSSLSocket.cpp这个文件在编译时会出错,尽管修正后编译通过,但由于在后期使用libthrift.lib库时报错,这里工程中我把它移除出去了,实例中并不需要用到,编译通过的修改如下:
#99 移除::
#143
} else if (protocol == SSLv3) {
// { @zuolj The new openssl doesn't support SSLv3
//ctx_ = SSL_CTX_new(SSLv3_method());
throw TSSLException("SSL_CTX_new: Unsupport SSLv3");
// }
}

使用示例

设计thrift文件(IDL)

namespace cpp HelloThrift.Interfaceservice HelloService{    string HelloString(1:string para)    i32 HelloInt(1:i32 para)    bool HelloBoolean(1:bool para)    void HelloVoid()    string HelloNull()}

通过IDL工具生成源代码

# 执行thirift命令生成源文件:thrift-0.9.3.exe --gen cpp Hello.thrift

以上命令生成C++语言的源代码,然后会生成一个gen-cpp目录,里面包含自动生成的几个源代码文件:
gen-cpp

实现server程序

HelloService_server.skeleton.cpp就是默认的server端程序入口,拷贝一份重命名为server.cpp,通过VS2015新建工程,将gen-cpp目录下的所有文件复制到新工程下,设置头文件包含和lib库目录。 比如设置libthrift.lib的头文件目录为thrift-0.9.3\lib\cpp\src,lib库目录为thrift-0.9.3\lib\cpp\x64\Debug。
在server.cpp中添加代码逻辑,然后编译。

class HelloServiceHandler : virtual public HelloServiceIf { public:  HelloServiceHandler() {    // Your initialization goes here  }  void HelloString(std::string& _return, const std::string& para) {    // Your implementation goes here    printf("HelloString,I got your name %s\n",para.c_str());    _return = "give you back";  }  int32_t HelloInt(const int32_t para) {    // Your implementation goes here    printf("HelloInt\n");    return para;  }  bool HelloBoolean(const bool para) {    // Your implementation goes here    printf("HelloBoolean\n");    return para;  }  void HelloVoid() {    // Your implementation goes here    printf("HelloVoid\n");  }  void HelloNull(std::string& _return) {    // Your implementation goes here    printf("HelloNull\n");  }};

实现client程序

通过VS2015新建工程,将gen-cpp目录下的所有文件复制到新工程下(除HelloService_server.skeleton.cpp之外),并增加上面手动实现的client.cpp,设置头文件包含和lib库目录。

#include <stdio.h>#include <string>#include <thrift/transport/TSocket.h>#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/server/TSimpleServer.h>#include <thrift/transport/TServerSocket.h>#include <thrift/transport/TBufferTransports.h>#include "Hello_types.h"#include "HelloService.h"#include "Hello_constants.h"using namespace ::apache::thrift;using namespace ::apache::thrift::protocol;using namespace ::apache::thrift::transport;using namespace ::apache::thrift::server;using namespace HelloThrift::Interface;using boost::shared_ptr;int main(int argc, char** argv){    shared_ptr<TTransport> socket(new TSocket("localhost", 9090));    shared_ptr<TTransport> transport(new TBufferedTransport(socket));    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));    HelloServiceClient client(protocol);    try    {        transport->open();        std::string para = "cpper.info";        std::string _return;        client.HelloString(_return,para);        printf("%s\n", _return.c_str());        client.HelloVoid();        client.HelloBoolean(true);        transport->close();    }    catch (TException& tx)    {        printf("ERROR:%s\n", tx.what());    }}

编译

运行server程序和client程序
这里写图片描述

所有工程文件已放到github上

原创粉丝点击