江苏省网站建设_网站建设公司_VS Code_seo优化
2026/1/19 17:08:42 网站建设 项目流程

什么是Protobuf

image

简单来说,Protobuf是代码世界的“通用翻译官”

跨语言:它让C++ 的结构体能被C#读懂,就像JSON 一样,但比JSON更强大。

高性能:它传输的是二进制(0101...),比文本格式的JSON体积小得多,解析速度快10倍以上。

强契约:通过.proto文件定义数据结构,一旦定义好,类型就是安全的。

场景重现

假设我们的 C++ 工程目录结构如下,不仅有子文件夹,还有跨文件夹的引用(Import):

MyProject/
├── proto/                  <-- 【关键】这是 Proto 的根目录
│   ├── common/             <-- 公共基础库
│   │   └── geometry.proto  <-- 定义了 Point3D 等基础类型
│   └── robot/              <-- 具体的业务模块
│       └── status.proto    <-- 这里引用了 common/geometry.proto
└── MyCSharpApp/            <-- 我们的 C# 项目└── MyCSharpApp.csproj

基础文件:common/geometry.proto

syntax = "proto3";
package common;
option csharp_namespace = "SmartLogistics.Common";message Point3D {double x = 1;double y = 2;double z = 3;
}

业务文件:robot/status.proto

它引用了common目录下的文件

syntax = "proto3";
package robot;
option csharp_namespace = "SmartLogistics.Robot";// 注意这里的路径:它是基于 proto/ 根目录写的
import "common/geometry.proto"; 
import "google/protobuf/timestamp.proto";message VehicleStatus {string device_id = 1;// 直接使用了引用的类型common.Point3D current_location = 2; google.protobuf.Timestamp last_updated = 3;
}

解决方案

1、创建一个.Net的项目,把这些文件包括在其中

image

image

2、将proto目录整体放入项目中来

image

3、给当前项目安装Nuget依赖

  • Google.Protobuf
  • Grpc.Tools (编译工具)
  • Grpc.Net.Client (可选,如果涉及 gRPC 通讯)

image

image

4、双击当前项目进入项目文件编辑

image

添加一个ItemGroup节点

<ItemGroup><Protobuf Include="proto\**\*.proto"ProtoRoot="proto"GrpcServices="Client" />
</ItemGroup>

image

5、直接重新生成即可

image

这时候这些proto对应的.cs文件就在/obj目录下,如果你顺利看到你要的cs文件,说明前面的配置对了,如果没看到说明前面的配置有问题,尤其是注意刚才那个ItemGroup节点对应的路径哈。

image

6、使用

using System;
using Google.Protobuf.WellKnownTypes; // 用于 Timestamp
using SmartLogistics.Common;          // 自动生成的命名空间
using SmartLogistics.Robot;namespace MyCSharpApp
{internal class Program{static void Main(string[] args){// 创建一个复杂的嵌套对象var status = new VehicleStatus{DeviceId = "AGV-2026-X1",// 直接使用引用的 Point3D 类型CurrentLocation = new Point3D { X = 10.5, Y = 20.1, Z = 0 },// 使用 Google 标准时间戳LastUpdated = Timestamp.FromDateTime(DateTime.UtcNow)};Console.WriteLine($"设备 {status.DeviceId} 位置: ({status.CurrentLocation.X}, {status.CurrentLocation.Y})");// 序列化为二进制(模拟发送给 C++ 端)byte[] bytes = status.ToByteArray();Console.WriteLine($"序列化后大小: {bytes.Length} 字节");}}
}

image

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询