2014-11-23 146 views
0

我遇到了靜態初始化期間實例化的protobuf消息的問題。一些像DebugPrint()這樣的函數會導致崩潰,並且序列化會失敗,並出現大小不匹配的錯誤。全局protobuf消息

考慮到https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details並查看生成的mymessage.pb.cc文件,我認爲問題是該消息的靜態初始化程序尚未被調用。

有沒有人知道我是否可以用某種「合法」的方式強制執行消息的靜態初始化函數(或者我稱之爲)?從查看生成的代碼我可以調用一些神奇的出現函數,但這似乎可能會中斷。或者,這只是我必須忍受的事情,並初始化消息懶惰?

回答

1

在嘗試使用MyType之前,請嘗試至少撥打MyType::default_instance()一次。這會觸發一堆可能會滿足您需求的初始化。

如果這不起作用,那麼你將需要找到某種方法來讓.pb.o的動態初始化器在你自己的代碼之前運行。這可能取決於鏈接器命令行中列出對象的順序,並且可以通過更改該順序來「修復」問題,但這顯然是非常糟糕的黑客行爲。

如果這樣也行不通,那麼你的運氣不好。不要依賴動態初始化,請考慮在首次使用時使用pthread_once或Win32的InitOnce初始化數據。

FWIW,Cap'n Proto,來自同一作者(我)的Protobufs的更新替代方案,具有嚴格的無動態初始化策略,所以不存在這種問題。 (靜態初始化)是指在編譯時已知結果內存內容的初始化程序,因此不需要在啓動時執行代碼,其中包括例如原始類型的全局變量或動態初始化「是指在啓動時運行的構造函數,這就是你在這裏討論的內容。不可否認,幾乎每個人都會得到這個錯誤,包括我自己在內的歷史上。)

+0

我實際上在默認的:: instance()非常有希望。然而它似乎沒有什麼區別:-(鏈接順序是我真正想要避免的破解 – BillP 2014-11-24 06:42:25

+0

那麼,你需要使用延遲初始化,無論如何這可能是個好主意。可能導致大型應用程序啓動時間過慢 - 例如,Chrome在使用protobufs時遇到了很多問題,這就是爲什麼我在Cap'n Proto中避免使用動態初始化程序的原因。另請參閱[我的關於單身人士](http://www.object-oriented-security.org/lets-argue/singletons),這可能與你的設計有關。祝你好運! – 2014-11-26 05:51:08