在C++项目中调用gRPC服务需要完成proto文件定义、代码生成、客户端逻辑编写以及编译链接等多个步骤,整个过程配合Protocol Buffers可以高效实现跨进程的数据交互。

环境准备
首先需要在系统中安装gRPC和Protocol Buffers相关依赖,以Ubuntu系统为例,可以通过以下命令安装基础依赖:
# 安装编译工具和依赖库 sudo apt update sudo apt install -y build-essential autoconf libtool pkg-config cmake # 克隆gRPC源码并编译安装 git clone --recurse-submodules -b v1.46.0 https://github.com/grpc/grpc.git cd grpc mkdir -p cmake/build cd cmake/build cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF ../.. make -j $(nproc) sudo make install sudo ldconfig
定义proto文件
proto文件用于定义服务接口和消息结构,是gRPC和Protocol Buffers工作的基础。我们定义一个简单的用户查询服务,文件命名为user_service.proto:
syntax = "proto3";
package user;
// 定义请求消息
message GetUserRequest {
int32 user_id = 1;
}
// 定义响应消息
message GetUserResponse {
int32 user_id = 1;
string user_name = 2;
string email = 3;
}
// 定义用户服务
service UserService {
rpc GetUser (GetUserRequest) returns (GetUserResponse) {}
}
生成C++代码
使用protoc工具结合gRPC插件生成对应的C++代码,执行以下命令:
# 生成protobuf消息类和gRPC服务代码 protoc --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` user_service.proto
执行后会生成四个文件:user_service.pb.h、user_service.pb.cc、user_service.grpc.pb.h、user_service.grpc.pb.cc,这些文件包含了消息序列化、反序列化以及gRPC服务调用的基础实现。
编写客户端调用代码
接下来编写C++客户端代码,实现调用gRPC服务的逻辑,文件命名为user_client.cpp:
#include <iostream>
#include <string>
#include "user_service.pb.h"
#include "user_service.grpc.pb.h"
// 简化grpc和protobuf命名空间使用
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using user::GetUserRequest;
using user::GetUserResponse;
using user::UserService;
// 用户服务客户端类
class UserClient {
public:
UserClient(std::shared_ptr<Channel> channel)
: stub_(UserService::NewStub(channel)) {}
// 调用GetUser接口
bool GetUserInfo(int32_t user_id, std::string* user_name, std::string* email) {
// 构造请求
GetUserRequest request;
request.set_user_id(user_id);
// 构造响应和上下文
GetUserResponse response;
ClientContext context;
// 发起RPC调用
Status status = stub_->GetUser(&context, request, &response);
// 处理调用结果
if (status.ok()) {
*user_name = response.user_name();
*email = response.email();
return true;
} else {
std::cout << "RPC调用失败: " << status.error_message() << std::endl;
return false;
}
}
private:
std::unique_ptr<UserService::Stub> stub_;
};
int main(int argc, char** argv) {
// 连接gRPC服务端,假设服务端运行在本地50051端口
UserClient client(grpc::CreateChannel(
"127.0.0.1:50051", grpc::InsecureChannelCredentials()));
// 调用接口查询用户ID为1的用户信息
std::string user_name;
std::string email;
if (client.GetUserInfo(1, &user_name, &email)) {
std::cout << "查询成功,用户ID: 1" << std::endl;
std::cout << "用户名: " << user_name << std::endl;
std::cout << "邮箱: " << email << std::endl;
}
return 0;
}
编译与运行
使用CMake管理编译流程,编写CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.10)
project(user_client)
# 查找gRPC和Protobuf依赖
find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)
# 添加生成的proto代码
set(PROTO_SRCS user_service.pb.cc user_service.grpc.pb.cc)
# 添加可执行文件
add_executable(user_client user_client.cpp ${PROTO_SRCS})
# 链接依赖库
target_link_libraries(user_client
gRPC::grpc++
Protobuf::libprotobuf
)
编译并运行客户端:
mkdir build cd build cmake .. make # 确保服务端已经启动,再运行客户端 ./user_client
注意事项
- proto文件的语法版本需要和安装的protoc工具版本匹配,避免生成代码时出现语法错误
- 客户端连接服务端的地址和端口需要和实际运行的服务端配置一致,否则会调用失败
- 实际生产环境中建议使用安全的通道凭证,而不是示例中的
InsecureChannelCredentials - 如果服务端返回的错误信息需要更详细的排查,可以通过
status.error_details()获取更多错误上下文
C++gRPCProtocol_Buffersprotobuf修改时间:2026-06-27 05:48:29