protobuf-net中的动态protobuf消息

时间:2014-12-09 13:35:21

标签: c# c++ protobuf-net

我正在构建插件架构。用户可以构建自己的插件,并允许他们将自己的插件设置放在protobuf中(我不知道用户会在那里放置什么类型)。

Protos消息:

message pbPlugin{
    required string id = 1; 
    required string type = 2;
    optional bytes settings = 3;
    optional bytes settings_descriptor= 4;
}

message pbMyPluginSetting{
    optional double exposure=1;
    optional int32 pixel_clock=2;
}

服务器端(c ++):

int main(int argc, char *argv[])
{
pbPlugin* pb_plugin;

pbMyPluginSetting plugin_settings; //it's user class i don't know it
plugin_settings.set_exposure(7);
plugin_settings.set_pixel_clock(28);

void *plugin_settings_buffer = malloc(plugin_settings.ByteSize());
plugin_settings.SerializeToArray(plugin_settings_buffer , plugin_settings.ByteSize());

pbPlugin->set_settings(plugin_settings_buffer , plugin_settings.ByteSize());

const Descriptor* desc=plugin_settings.GetDescriptor();
void *plugin_settings_desc_buffer = malloc(desc.ByteSize());
plugin_settings.SerializeToArray(plugin_settings_desc_buffer , desc.ByteSize());

pbPlugin->settings_descriptor(plugin_settings_desc_buffer , desc.ByteSize());
}

因此,用户正在制作他自己的protobuf消息,并且他正在对其进行序列化,并将其置于pbPlugin消息的设置字段中,并且他正在序列化此消息描述符。

现在在客户端(c#应用程序)我正在收到我的pbPlugin消息,我想反序列化设置字段,并更改曝光和pixel_clock。我的问题是,我不知道如何在不知道其类型的情况下反序列化消息?可以在protobuf-net吗?

在c ++中我会使用描述符我已经序列化并DynamicMessageFactory来创建消息以放入反序列化的设置。

DynamicMessageFactory dmf;
Message* actual_msg = dmf.GetPrototype(deserialized_descriptor)->New();

这样我可以访问和更改字段值。 我怎么能实现它protobuf-net

1 个答案:

答案 0 :(得分:0)

经过进一步调查后,我找到了解决这个问题的方法。遗憾的是,使用protobuf-net似乎是不可能的,但使用protobuf-sharp-port非常容易。我已经替换了库,从那里你可以像这样访问文件描述符。

-get文件描述符:

global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto fdp= global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.ParseFrom(settings_descriptors);

-get消息描述符:

global::Google.ProtocolBuffers.Descriptors.MessageDescriptor descriptor= fdp.MessageTypes[0];

从那里你可以获得动态信息:

Google.ProtocolBuffers.DynamicMessage dynamic_message = Google.ProtocolBuffers.DynamicMessage.GetDefaultInstance(descriptor);

希望它能帮助有同样问题的人。