全球原型消息

Global protobuf message

本文关键字:消息 原型      更新时间:2023-10-16

我在静态初始化期间实例化的 protobuf 消息遇到问题。某些函数(如 DebugPrint() 会导致崩溃,并且序列化失败,并出现大小不匹配的错误。

考虑到 https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details 并查看生成的 mymessage.pb.cc 文件,我认为问题是消息的静态初始值设定项尚未调用。

有谁知道我是否可以以一种有点"合法"的方式强制执行消息的静态初始值设定项是事先调用的(或者我调用它们)?通过查看生成的代码,我可以调用一些神奇的函数,但这似乎可能会中断。或者这只是我必须忍受并懒惰地初始化消息的东西?

在尝试使用 MyType 之前,请尝试至少调用一次MyType::default_instance()。这会触发一系列可能满足您的需求的初始化。

如果这不起作用,那么您将需要找到某种方法使 .pb.o 的动态初始值设定项在您自己的代码之前运行。这可能取决于对象在链接器命令行上列出的顺序,您可以通过更改该顺序来"修复"问题,尽管这显然是一个可怕的黑客。

如果这也不起作用,那么你就不走运了。请考虑使用 pthread_once 或 Win32 的InitOnce在首次使用时初始化数据,而不是依赖动态初始化。

FWIW,Cap'n Proto,来自同一作者(我)的Protobufs的较新替代品,具有严格的无动态初始值设定项策略,因此没有这种问题。

(术语吹毛求疵:"静态初始化"是指初始值设定项,其中生成的内存内容在编译时是已知的,因此不需要在启动时执行代码。这包括例如基元类型的全局或constexpr s."动态初始化"是指在启动时运行的构造函数,这就是您在这里谈论的内容。诚然,几乎每个人都弄错了,包括历史上的我自己。