jea*_*ean 2 c# protocol-buffers
我正在使用官方的 c# protobuf(不是 Protobuf-net)。是否支持根据消息类型创建消息对象?
\n\n典型的反序列化就像\xef\xbc\x9a
\n\nMyProtoMessageClass obj = MyProtoMessageClass.Parser.ParseFrom(byteArray);\nRun Code Online (Sandbox Code Playgroud)\n\n但是如何根据字符串生成实例
\n\n"MyProtoMessageClass"\nRun Code Online (Sandbox Code Playgroud)\n\n或者Google.Protobuf.Reflection.MessageDescriptor其中的一个对象是
MyProtoMessageClass.Descriptor\nRun Code Online (Sandbox Code Playgroud)\n\n?
\n\n更新
\n\ndelegate 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);\nRun Code Online (Sandbox Code Playgroud)\n
假设我们得到了这个原型定义:
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)