protobuf 和 .net - 如何使用生成的 .cs 文件?

Posted

技术标签:

【中文标题】protobuf 和 .net - 如何使用生成的 .cs 文件?【英文标题】:protobuf and .net - how do I use the generated .cs file? 【发布时间】:2016-04-12 03:47:02 【问题描述】:

我开始使用 protobufs - 我有一个 proto 文件:

syntax = "proto2";

message InputState 
    required uint32 input = 1;
    required string state = 2;


message InputStateData 
    repeated InputState input = 1;

我运行了命令行工具(来自 protoc-3.0.0-alpha-3-win32)

我收到了这个意外的 .cs 文件: !click me! Input.cs

我包含了 nuget protobuf-portable-net,但现在我不知道如何使用生成的 .cs 文件

接下来我该怎么做 - Input.cs 文件是否正确?

【问题讨论】:

将该文件添加到您的.csproj 并使用它。 @Dai 检查 Input.cs,据我所见,该文件在 c# 中不可用 是什么让您认为它无法使用?我觉得很好。 @Dai 在我将它包含在 c# 项目中时无法编译 我试过这个silentorbit.com/protobuf/examples 并且输出完全不同并且已编译 - 我一定对官方工具有误解 【参考方案1】:

.net 中有两个完全独立的工具(至少)可以使用“protobuf”。看起来您正在使用 tooling 从一个(Jon 的版本,以前是“protobuf-csharp-port”,但现在是 Google 代码库 IIRC 的一部分),但使用的是库来自另一个(protobuf-net)。那是行不通的!库必须匹配的工具。

如果你想使用 protobuf-net:要么单独使用 protobuf-net 库(它支持“代码优先”,意思是:没有工具),或者使用 protobuf-net 工具和 protobuf-net 库。

如果您想使用 protobuf-csharp-port(现在可能只是“protobuf”):使用其中的工具和库。

有关信息,对于使用 protobuf-net 的代码优先方法,如果您不想使用构建步骤,可以手动翻译简单的合同:

[ProtoContract]
class InputState 
    [ProtoMember(1)]
    public uint Input get;set;
    [ProtoMember(2)]
    public string State get;set;

[ProtoContract]
class InputStateData 
    [ProtoMember(1)]
    public List<InputState> Input get; = new List<InputState>();

【讨论】:

谢谢!我希望你能提供你的意见。您发布的示例是我期望生成器创建的。有没有发电机可以做到这一点?还有,为什么protoc工具会生成这么复杂的文件? @pogorman protobuf-net 中的protogen 工具输出如下内容;至于“为什么”:因为 protoc 就是这样设计的 我想与嵌入式系统(用 C 编写的软件)进行通信。将要通信的结构将始终在嵌入式端定义。我们将在嵌入式端使用 nanopb。我希望使用嵌入式的 proto 文件并生成上面发布的类。这甚至可能吗?还是我应该使用标准的协议工具?你认为最好的 c# 文件生成器是什么?再次感谢。【参考方案2】:

好的 - 我正在学习更多,这是提供最接近我预期格式的文件生成器:https://github.com/floatinghotpot/protogen(用于 protobuf-net)。这正是我所需要的。

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool. 
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
    //------------------------------------------------------------------------------

// Generated from: inputs.proto
namespace inputs

[global::System.Serializable,  global::ProtoBuf.ProtoContract(Name=@"InputState")]
 public partial class InputState : global::ProtoBuf.IExtensible

public InputState() 

private uint _input;
[global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"input", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
public uint input

  get  return _input; 
  set  _input = value; 

private string _state;
[global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"state", DataFormat = global::ProtoBuf.DataFormat.Default)]
public string state

  get  return _state; 
  set  _state = value; 

private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
   return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); 


 [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"InputStateData")]
 public partial class InputStateData : global::ProtoBuf.IExtensible

public InputStateData() 

private readonly global::System.Collections.Generic.List<InputState> _input = new global::System.Collections.Generic.List<InputState>();
[global::ProtoBuf.ProtoMember(1, Name=@"input", DataFormat = global::ProtoBuf.DataFormat.Default)]
public global::System.Collections.Generic.List<InputState> input

  get  return _input; 


private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
   return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); 



【讨论】:

以上是关于protobuf 和 .net - 如何使用生成的 .cs 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 protobuf-net 处理 .proto 文件

Protobuf-net 对 Dictionary/KeyValuePair 的支持如何工作?

如何在 xamarin ios pcl 中使用 protobuf-net

用于继承的 Protobuf-net .proto 文件生成

protobuf-net 生成的 .proto 文件中的字段命名约定不正确?

编译 protobuf-net 生成的代码时出错