Protobuf.NET使用

需要在托管c#和非托管c ++之间发送一些数据。 经过一番研究后,我尝试使用Protobuf.NET。

我不确定我是否理解ProtoBuf的function……

  1. 在Proto中构建一个类型定义。 我在c ++和c#项目中都需要这种类型定义
  2. 使用命令行工具“protogen.exe”从类型定义中获取.cs文件和.cpp,.h
  3. 将.cs文件复制到我的c#项目和我的c ++解决方案中的.cpp,.h。

似乎我愚蠢地解决这个问题。 这是我的问题和疑问。

  1. 是否可以在c#中定义类型以生成c ++中的文件?
  2. 试图使用命令行工具protogen.exe与以下文件

test1.proto

using ProtoBuf; namespace ProtocolBuffers { [ProtoContract] class Person { [ProtoMember(1)] public int Id {get;set;} [ProtoMember(2)] public string Name { get; set; } } } 

test2.proto

 message Person { required int32 id = 1; required string name = 2; optional string email = 3; } 

没有什么对我有用。 真的尝试了一切。 我将proto文件放入命令行目录,尝试了每个选项来设置目录。 如何轻松构建它们? 第二个文件正在使用c ++的标准proto命令行工具,但我也需要它用于c#。 真的需要你的帮助。

首先,请注意protobuf-net只是.NET的一个可用实现; 无论如何…

“test1.proto”不是.proto – 它是C#; 使用protobuf-net 不需要 .proto,但在你的互操作方案中,这是一个非常好的主意。 有VS2010插件,或者protobuf-net zip中的protogen工具:

  protogen -i:test2.proto -o:test2.cs 

这应该生成带有内容的test2.cs

 //------------------------------------------------------------------------------ //  // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. //  //------------------------------------------------------------------------------ // Generated from: test2.proto namespace test2 { [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Person")] public partial class Person : global::ProtoBuf.IExtensible { public Person() {} private int _id; [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"id", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)] public int id { get { return _id; } set { _id = value; } } private string _name; [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"name", DataFormat = global::ProtoBuf.DataFormat.Default)] public string name { get { return _name; } set { _name = value; } } private string _email = ""; [global::ProtoBuf.ProtoMember(3, IsRequired = false, Name=@"email", DataFormat = global::ProtoBuf.DataFormat.Default)] [global::System.ComponentModel.DefaultValue("")] public string email { get { return _email; } set { _email = value; } } private global::ProtoBuf.IExtension extensionObject; global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } } } 

请注意,如果您需要其他开关,例如,它可以尝试进行大小写规范化(因此您获得IdNameEmail等),或者希望它包含其他序列化程序支持( BinaryFormatterDataContractSerializer等)

test1.proto不是有效的.proto文件。

test2.proto看起来很不错。 请注意,您需要主protobuf项目中的编译器以生成C ++代码,并且需要来自protobuf-net的编译器以生成C#代码。 我想你的大部分问题都来自于没有意识到你需要两个不同的编译器(但你将相同的.proto文件提供给两者)。

虽然我对ProtoBuf了解不多,但我知道有一种更简单的方法可以做到这一点。 如果上面的类表示您尝试发送到C ++的数据,只需使用序列化并序列化您的类,然后您可以将类和数据输出到XML文件。 然后,您可以使用XmlLite或其他一些XML阅读器来读取您的类和数据。 您甚至可以使用Boost读取序列化类。