今天遇到奇葩问题 解析string始终不对
这里搜集一下网上的说法:
The C++ implementation of protocol buffers returns the byte and string types as std::string
. This structure contains a length function telling you how long the corresponding data is (as well as the data itself.) Thus there is no special significance of embeded \0
characters.
The setting functions accept a string too, or there are versions that accept a buffer and length. If you want to set a field you can just do this:
pb.set_foo( std::string( data, data_length ) );
or
pb.set_foo( data, data_length )
A follow-up to my own previous comment - I figured out how to do enums and optional types. The latter is done via nullable types, I never saw that documented here.
If anyone knows how to encode default values, I would love to hear about it.
Meanwhile, here's a demo proto definition and its corresponding proto.net implemenation. Hope that helpful to someone:
// ----------------------------------------------------------------------------- // DemoMessage.proto // ----------------------------------------------------------------------------- message DemoMessage { message WildThing { enum Coolness { COOLNESS_NOT_SO_MUCH = 0; COOLNESS_EXTREMELY_SO = 1; } optional Coolness coolness = 1 [default = COOLNESS_NOT_SO_MUCH]; optional float toxicity_PPM = 2 [default = 0.12]; } optional InnerThing wildThing = 1; optional uint64 posixTime_Msec = 2; optional float volume_dBm = 3 [default = -112.0]; } // ----------------------------------------------------------------------------- // Proto.DemoMessage.cs // ----------------------------------------------------------------------------- using System; using System.IO; using ProtoBuf; // ----------------------------------------------------------------------------- namespace Whatever { // ------------------------------------------------------------------------- [ProtoContract] public sealed class Proto_DemoMessage { [ProtoContract] public sealed class WildThingMessage { public enum CoolnessSetting { NotSoMuch = 0, ExtremelySo = 1 } [ProtoMember(1, IsRequired = false)] public CoolnessSetting? Coolness { get; set; } [ProtoMember(2, IsRequired = false)] public float? Toxicity_PPM { get; set; } } [ProtoMember(1, IsRequired = false)] public WildThingMessage WildThing { get; set; } [ProtoMember(2, IsRequired = false)] public UInt64? PosixTime_Msec { get; set; } [ProtoMember(3, IsRequired = false)] public float? Volume_dBm { get; set; } // --------------------------------------------------------------------- // --------------------------------------------------------------------- public byte[] Serialize() { byte[] b = null; using (var ms = new MemoryStream()) { Serializer.Serialize<Proto_DemoMessage>(ms, this); b = new byte[ms.Position]; var fullB = ms.GetBuffer(); Array.Copy(fullB, b, b.Length); } return b; } // --------------------------------------------------------------------- public static Proto_DemoMessage Deserialize(byte[] serializationBytes) { Proto_DemoMessage m = null; using (var ms = new MemoryStream(serializationBytes)) { m = Serializer.Deserialize<Proto_DemoMessage>(ms); } return m; } } }Hello, standart BinnaryWriter? is faster then ProtoBuf?, why ? Here is my code:
private static void Main(string[] args) { Test test = new Test(); test.Name = "TestName"; //=====BinaryFormatter var st = new Stopwatch(); st.Start(); var formatter = new BinaryFormatter(); for (int i = 0; i < 100; i++) { using (var stream = new MemoryStream()) { stream.Position = 0; formatter.Serialize(stream, test); stream.Position = 0; var result = (Test)formatter.Deserialize(stream); string name = result.Name; stream.Close(); } } st.Stop(); Console.WriteLine("BinaryFormatter = " + st.ElapsedMilliseconds); //======ProtoBuf st.Reset(); st.Start(); for (int i = 0; i < 100; i++) { using (var stream = new MemoryStream()) { stream.Position = 0; Serializer.Serialize(stream, test); stream.Position = 0; var result = Serializer.Deserialize<Test>(stream); string name = result.Name; stream.Close(); } } st.Stop(); Console.WriteLine("ProtoBuff = " + st.ElapsedMilliseconds); } [ProtoContract] [Serializable] internal class Test { [ProtoMember(1)] public string Name { get; set; } }The result is: BinaryFormatter? = 6 msec ProtoBuf? = 352 msec
https://github.com/hultqvist/protobuf