乐闻世界logo
搜索文章和话题

如何在 C 中生成. Proto 文件或使用“Code First gRPC”

1 个月前提问
1 个月前修改
浏览次数32

1个答案

1

在C语言中生成 .proto 文件或使用 Code First gRPC 的方法相对有限,因为C语言不支持原生的gRPC Code First 开发方式。通常,我们会使用其他支持 Code First 的语言来生成 .proto 文件,然后再将这些文件用于C项目中。但是,我可以为你提供一种可能的方法来在C语言项目中使用gRPC,并解释如何生成 .proto 文件。

步骤1: 创建.proto文件

首先,你需要创建一个 .proto 文件,这个文件定义了你的服务接口和消息格式。这不是特定于任何编程语言的,而是一种跨语言的方式来定义接口。例如:

proto
syntax = "proto3"; package example; // 定义一个服务 service Greeter { // 定义一个RPC方法 rpc SayHello (HelloRequest) returns (HelloReply); } // 定义消息格式 message HelloRequest { string name = 1; } message HelloReply { string message = 1; }

步骤2: 使用protoc生成C代码

一旦你有了 .proto 文件,你可以使用 protoc 编译器来生成C语言的源代码。gRPC支持多种语言,但对C的支持通过一个叫做gRPC C Core的库来实现。你需要安装 grpcgrpc-tools 来生成C语言的gRPC代码。

在命令行中,可以使用以下命令:

bash
protoc -I=. --c_out=. ./example.proto

注意:这里假设不存在直接的 --c_out 选项,因为官方的gRPC对C的支持主要是通过C++ API。实际上,你可能需要生成C++代码,然后通过C语言调用C++代码。

步骤3: 在C项目中使用生成的代码

生成的代码通常包括对应的服务接口和请求/响应消息的序列化和反序列化函数。在你的C或C++项目中,你需要将这些生成的文件包含进来,并且编写相应的服务器和客户端代码来实现定义在 .proto 文件中的接口。

示例: C++服务器和C客户端

假设你生成了C++的服务代码,你可以写一个C++服务器:

cpp
#include <grpcpp/grpcpp.h> #include "example.grpc.pb.h" class GreeterServiceImpl final : public example::Greeter::Service { grpc::Status SayHello(grpc::ServerContext* context, const example::HelloRequest* request, example::HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); return grpc::Status::OK; } }; void RunServer() { std::string server_address("0.0.0.0:50051"); GreeterServiceImpl service; grpc::ServerBuilder builder; builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.RegisterService(&service); std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; server->Wait(); } int main() { RunServer(); return 0; }

然后,你可以尝试通过C调用这些服务,尽管通常需要C++客户端来与之交互或者使用专用的C库如 grpc-c

总结

在C语言中直接使用 Code First gRPC 是有挑战性的,主要是因为C语言的限制和gRPC官方的支持偏向现代语言。一个可行的路径是使用C++作为中介或查看是否有第三方库提供了这样的支持。尽管这个过程可能涉及到C++,但你仍然可以将核心功能保留在C语言中。

2024年7月24日 01:09 回复

你的答案