C++ GRPC编译及使用

说明

本例的环境为:WIN10 + VS2015
gRPC 的版本为: 1.35.1
protobuf 的版本为: 3.3.2

准备工作

  1. 本例使用 VS2015 进行编译,其他版本的 VS 没有试过,不过大致步骤应该差不多。
  2. 确保环境变量 PATH 包含 git.exe 所在目录,因为我们要通过 git 下载 gRPC 源码。
  3. 下载并安装 Active State
    Perl。本例下载的是:ActivePerl-5.24.1.2402-MSWin32-x86-64int-401627.exe。安装后打开命令行,输入以下命令验证安装,如果出现版本信息,就说明安装成功了。
	> perl -v
	
	This is perl 5, version 24, subversion 1 (v5.24.1) built for MSWin32-x86-multi-thread-64int
	(with 1 registered patch, see perl -V for more detail)
  1. 下载并安装 Go 注意:你可能需要设置代理来下载)。本例下载的是:go1.8.3.windows-amd64.msi。安装后打开命令行,输入以下命令验证安装,如果出现版本信息,就说明安装成功了。

    go version
    go version go1.8.3 windows/amd64

下载源码

  1. 打开命令行,新建一个目录专门用来放置 gRPC 的源码,然后进入该目录。本例是在 G 盘下建立的 grpc
    目录,大家应该根据实际情况修改。

    cd G:
    md grpc & cd grpc

  2. 用 git 下载 gRPC 源码,本例下载的版本是 1.4.2 。

    git clone -b v1.4.2 https://github.com/grpc/grpc.git grpc_v1.4.2

  3. 下载后可以在源码根目录找到 INSTALL.md,里面详细介绍了编译方法。

  4. 下载源码后,可以在源码根目录下找到 .gitmodules 文件,该文件是 git 用来描述依赖库的,可以看到 gRPC 的依赖库有:protobuf,gflags,googletest,boringssl,cares,zlib。这些依赖库都需要下载到 third_party 目录下。可以执行以下命令下载这些依赖库,也可以跳过这一步,转到第 5 步开始手动下载。

    git submodule update --init

  5. 进入到 third_party 目录,下面开始下载 gRPC 的依赖库。

    cd third_party

  6. 下载 protobuf,这里下载的版本是 3.3.2。

    git clone -b v3.3.2 https://github.com/google/protobuf.git protobuf

  7. 下载 gflags。

    git clone https://github.com/gflags/gflags.git gflags

  8. 下载 googletest 。

    git clone https://github.com/google/googletest.git googletest

  9. 下载 boringssl 。

    git clone https://github.com/google/boringssl.git boringssl

  10. 下载 cares 。需要注意下载的版本为:cares-1_12_0 。下载的目录为 cares\cares 。

    git clone -b cares-1_12_0 https://github.com/c-ares/c-ares.git cares/cares

  11. 下载 zlib 。

    git clone https://github.com/madler/zlib.git zlib

编译

  1. 找到 third_party\boringssl 目录下的 CMakeLists.txt,用编辑器打开它,搜索
    MSVC_DISABLED_WARNINGS_LIST,找到后,在下面添加
    “C4819”,消除警告:该文件包含不能在当前代码页(数字)中表示的字符。 以 Unicode 格式保存该文件防止数据丢失。

  2. 切换到源码目录,在源码目录下创建一个 .build (如果要编译64位,则是
    .build_x64)子目录,我们用该目录保存所有生成的工程文件。创建后进入该目录。

    32位:

    md .build & cd .build
    64位:

    md .build_x64 &cd .build_x64

  3. 用 cmake 生成工程文件。生成后可以在 .build (或 .build_x64)目录下看到生成的工程和项目文件。

    32位:

    cmake … -G “Visual Studio 14 2015” -DCMAKE_BUILD_TYPE=Release
    64位:

    cmake … -G “Visual Studio 14 2015 Win64” -DCMAKE_BUILD_TYPE=Release

  4. 使用 MSBuild 编译工程。打开 VS2015 开发人员命令提示符,切换到 .build (或
    .build_x64)目录下,执行下面的命令进行编译。

    编译 32 位 Debug 版本:

    MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Debug;Platform=Win32

    编译 32 位 Release 版本:

    MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Release;Platform=Win32

    编译 64 位 Debug 版本:

    MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Debug;Platform=x64

    编译 64 位 Release 版本:

    MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Release;Platform=x64

如果遇到如下错误,则用编辑器打开.build\third_party\boringssl\crypto_test_data.cc ,在第 2604 行最后面的双引号 " 之前加个空格。保存,退出,重新编译。

> G:\grpc\grpc_v1.4.2\.build\third_party\boringssl\crypto_test_data.cc(2604): error C2001: 常量中有换行符

编译好之后,可以在相应项目目录下的 Debug 和 Release 子目录中找到我们需要的库和工具。如下所示(仅列出重要部分):

实例
下面写一个小程序测试一下。

新建 [空白解决方案],命名为 Calculator。如下图:

这里写图片描述
创建接口
添加 [Win32 控制台应用程序],命名为 ICalc。如下图:

这里写图片描述

在 [应用程序设置页面],勾选 [空项目]。如下图所示。点击完成。

这里写图片描述

将 .build\third_party\protobuf\Debug\protoc.exe 和 .build\Debug\grpc_cpp_plugin.exe 拷贝到项目目录中。拷贝后的目录如下所示:

这里写图片描述

新建 [C++ 文件(.cpp)],命名为 calculator.proto。注意一定要带 .proto 后缀,否则的话后缀就变成 .cpp 了。如下图所示:

这里写图片描述

calculator.proto 右键,[属性]。 [项类型] 选择 [自定义生成工具]。点击[应用] 按钮。如下图所示:

这里写图片描述

在 [自定义生成工具] -> [常规] 下,[命令行]填写如下命令:
protoc --cpp_out=. calculator.proto
protoc --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe calculator.proto
[说明] 填写 Performing Protoc Build Tools。[输出] 填写 None。[链接对象] 改为 [否]。 如下图所示:

这里写图片描述

打开 calculator.proto,编写如下代码:
syntax = “proto3”;

package calc;

service Caltulator {
rpc Add(Request) returns (Response) {}
}

message Request {
int32 a = 1;
int32 b = 2;
}

message Response {
int32 sum = 1;
}
编译项目,成功后会在项目目录中生成如下文件:

calculator.pb.h
calculator.pb.cc
calculator.grpc.pb.h
calculator.grpc.pb.cc
其中,calculator.pb.h 和 calculator.pb.cc 是通过 protoc.exe 编译生成的接口数据类型,在这里就是我们在 calculator.proto 中定义的 Request 和 Response。calculator.grpc.pb.h 和 calculator.grpc.pb.cc 是通过 grpc_cpp_plugin.exe 编译生成的服务器以及存根代码。有了这些文件,就可以开始编写服务器和客户端的代码了。

实现服务器
新建 [Win32 控制台应用程序],命名为 Server。如下图所示:

这里写图片描述

在 [应用程序设置] 页面,勾选 [空项目] 。如下图所示:

这里写图片描述

项目右键,[添加现有项],选择上面生成的那四个接口文件:

这里写图片描述

项目 [属性] -> [C/C++] -> [常规] -> [附加包含目录],加入 gRPC 和 Protocol Buffer 的头文件,如下图所示。注意这里应该换成自己实际的目录。

这里写图片描述

项目 [属性] -> [链接器] -> [常规] -> [附加库目录],添加 gRPC 及其依赖库的目录,如下图所示。注意这里应该换成自己实际的目录。

这里写图片描述

项目 [属性] -> [链接器] -> [输入] -> [附加依赖库],添加 gRPC 及其依赖的库,如下图所示。

这里写图片描述
工程 [属性] -> [C/C++] -> [预处理器] -> [预处理器定义],添加 _WIN32_WINNT=0x600。

新建 [C++ 文件(.cpp)],命名为 main.cpp,代码如下:

#include “…/ICalc/calculator.grpc.pb.h”

#include “grpc++/grpc++.h”

class CalcualtorService : public calc::Caltulator::Service
{
// 构造、析构
public:

// 接口实现

public:
virtual ::grpc::Status Add(::grpc::ServerContext* context,
const ::calc::Request* request, ::calc::Response* response) override
{
response->set_sum(request->a() + request->b());
return grpc::Status::OK;
}
};

int main()
{
std::string server_address(“0.0.0.0:50051”);

CalcualtorService service;

grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);

std::unique_ptr server(builder.BuildAndStart());

std::cout << "Server listening on " << server_address << std::endl;

server->Wait();

return 0;

}
编译工程。生成 Server.exe。

实现客户端
实现客户端的步骤和实现服务器的一样,只是最后的 main.cpp 不一样而已。这里简单列出步骤。

新建 [Win32 控制台应用程序],命名为 Client。
添加在创建接口那一步生成的四个文件:calculator.pb.h calculator.pb.cc calculator.grpc.pb.h calculator.grpc.pb.cc
接下来和服务器一样,设置好 [附加包含目录],[附加库目录],[附加依赖库]。
[预处理器定义] 添加 _WIN32_WINNT=0x600
新建 main.cpp,代码如下:

#include

#include “grpc++/grpc++.h”
#include “…/ICalc/calculator.grpc.pb.h”

class Client
{
public:
Client(std::shared_ptrgrpc::Channel channel)
: stub_(calc::Caltulator::NewStub(channel)) {}

google::protobuf::int32 Add(google::protobuf::int32 a, google::protobuf::int32 b)
{
    calc::Request request;
    request.set_a(a);
    request.set_b(b);

    calc::Response response;

    grpc::ClientContext context;

    grpc::Status status = stub_->Add(&context, request, &response);

    if (status.ok())
    {
        return response.sum();
    }
    else
    {
        return -1;
    }
}

private:
std::unique_ptrcalc::Caltulator::Stub stub_;
};

int main()
{
Client client(grpc::CreateChannel(
“localhost:50051”, grpc::InsecureChannelCredentials()));

auto result = client.Add(1, 2);
std::cout << "1 + 2 = " << result << std::endl;

return 0;

}
编译工程。生成 Client.exe。

测试
先启动 Server.exe,再启动 Client.exe。

你可能感兴趣的:(C/C++,c++,rpc)