我遇到了在静态初始化期间实例化的protobuf消息的问题。某些函数(如DebugPrint())会导致崩溃,并且序列化失败,并显示大小不匹配的错误。
考虑https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details并查看生成的mymessage.pb.cc文件,我认为问题是该消息的静态初始化程序尚未被调用。
是否有人知道我是否可以在某种程度上强制执行#34;预先调用消息的静态初始化程序(或者我称之为)的静态初始化程序?从查看生成的代码我可以调用一些神奇的函数,但这似乎可能会破坏。或者这只是我必须忍受的事情并将信息初始化为懒惰?
答案 0 :(得分:1)
尝试使用MyType::default_instance()
之前,请至少尝试拨打MyType
一次。这会触发一堆可能满足您需求的初始化。
如果这不起作用,那么您需要找到一些方法使.pb.o的动态初始化程序在您自己的代码之前运行。可能这取决于链接器命令行中列出对象的顺序,您可以修复"改变这个顺序的问题,虽然这显然是一个可怕的黑客。
如果这也不起作用,那么你运气不好。不要依赖于动态初始化,而是考虑使用pthread_once
或Win32' InitOnce
在首次使用时初始化您的数据。
FWIW,Cap'n Proto,来自同一作者(我)的Protobufs的新替代品,具有严格的无动态初始化策略,因此没有这种问题。
(术语nitpick:"静态初始化"指的是初始化器,其中生成的内存内容在编译时是已知的,因此在启动时不需要执行代码。这包括例如原始类型的全局变量或{{ 1}} s。"动态初始化"指的是在启动时运行的构造函数,这就是你在这里所说的。不可否认,几乎每个人都错了,包括我自己在历史上。)