2

我们使用协议缓冲区在本机 C++ 应用程序之间进行通信,而且还通过 protobuf-net r666 在本机 C++ 应用程序和 .NET 应用程序(都是 VS2012)之间进行通信。我们在 C++ 中严重依赖可用于可选元素的 has_ 函数。

例如,如果我们有一个带有可选 bool 字段的消息,它可能是未设置、设置为 true 或设置为 false。

在 C++ 中,这可以使用函数 has_field 进行检查,如果设置,则可以使用 get_field 函数获取内容。如果未设置,则调用 get_field,则 get 返回默认值,如果未显式设置,则为 false(对于布尔值)。

这在 C++ 中非常有效,但是,在 protobuf-net 中,我们似乎找不到等效的 has_ 函数,并且,当收到消息时,该字段被添加到消息中,并且它的内容被设置为默认值,是假的。该字段默认存在并不是灾难,但问题是没有has_函数来检查它是否在消息中设置。

请告知这是否是一个错误或者我们是否错过了 protobuf-net 中的某些内容并且这实际上是可能的

提前谢谢。维姆

4

1 回答 1

5

(我知道我们已经在问题跟踪器中介绍了这个- 这纯粹是为了可见性等)

这与从 .proto 文件生成类有关,在 protobuf-net 的情况下是通过 protogen 工具生成的。默认情况下,它不会创建等效的has_*方法,但这可以通过-p:detectMissing开关启用 - 这会导致它创建*Specified访问器。这里的命名是一个 .NET 习语,*Specified被其他一些 .NET 序列化程序和内部代码识别。它还生成一个私有ShouldSerialize*方法,这又有助于一些内部 .NET 代码。

在这个特定的案例中,有一个名为“value引起混乱”的成员的次要问题;该csharp.xslt文件现已更新以解决此问题。


更新:在完全托管的重写中,ShouldSerialize*()使用proto2语法时默认生成该方法(默认)。不需要额外的参数。添加该*Specified成员(它在.ShouldSerialize*()

请注意,在使用时proto3,对序列化规则的更改意味着这个概念不再有意义。一个值被序列化当且仅当它不是默认值时,它总是 null/false/zero/empty。没有“默认值但指定”的概念。因此,这些ShouldSerialize*()方法通常不再有用,并且不会生成。如果这有助于一些真正的编码场景,我愿意让它们选择性地生成proto3,它们基本上意味着“非默认”。

于 2013-09-20T07:17:08.060 回答