时间:2019-03-17 标签:c#protobufreflectionus

jea*_*ean 2 c# protocol-buffers

我正在使用官方的 c# protobuf(不是 Protobuf-net)。是否支持根据消息类型创建消息对象?

\n\n

典型的反序列化就像\xef\xbc\x9a

\n\n
MyProtoMessageClass obj = MyProtoMessageClass.Parser.ParseFrom(byteArray);\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是如何根据字符串生成实例

\n\n
"MyProtoMessageClass"\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者Google.Protobuf.Reflection.MessageDescriptor其中的一个对象是

\n\n
MyProtoMessageClass.Descriptor\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n

更新

\n\n
delegate void handler(object data);\nclass Wrapper\n{\n    public handler h;\n    public global::Google.Protobuf.IMessage m;\n}\nDictionary<ushort, Wrapper> dict = new Dictionary<ushort, Wrapper>();\n\n\n// register\nclass HandlerClass {\n    public void handle(object o) {\n        ProtoMessageClass data = (ProtoMessageClass)o;\n        // use data \n    }\n}\nh = HandlerClassObj.handle;\nm = new ProtoMessageClass();\ndict[1] = new Wrapper{h = h, m = m};\n\n// call\nushort cmd = 1;// from socket\nbyte[] dataRecv; // from socket\nvar w = dict[cmd];\nGoogle.Protobuf.IMessage msg = w.m.Descriptor.Parser.ParseFrom(dataRecv);\nw.h.Invoke(msg);\n
Run Code Online (Sandbox Code Playgroud)\n

Ash*_*deh 5

假设我们得到了这个原型定义:

syntax = "proto3";
package tutorial;
option csharp_namespace = "T1.Models";

message Person {
    int32 id = 1;
    string name = 2;
}
Run Code Online (Sandbox Code Playgroud)

编译这个 proto 文件,我们得到一个名为PersonImplements 的类Google.Protobuf.IMessage。该接口包含一个属性MessageDescriptor Descriptor { get; },该属性由类实现Person并返回 type 的公共静态属性MessageDescriptor

包含MessageDescriptor一个名为 的公共静态属性Parser,我们可以调用它ParseFrom(byteArray)的 。

代码:

var typ = Assembly.GetExecutingAssembly().GetTypes().First(t => t.Name == "Person"); //get the type using the string we got, here it is 'Person'
var descriptor = (MessageDescriptor)typ.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static).GetValue(null, null); // get the static property Descriptor
var person = descriptor.Parser.ParseFrom(byteArray); // parse the byte array to Person
Run Code Online (Sandbox Code Playgroud)