我没有在Protocol Buffers文档中找到任何用于C ++中的异常处理的内容。在Javadoc中,它明确定义了InvalidProtocolBufferException,但没有在C ++中定义。
有时候我运行我的程序,当它在它认为有效的消息中找到缺少的字段时崩溃,然后它就会停止并抛出这样的错误:
[libprotobuf FATAL google/protobuf/message_lite.cc:273] CHECK failed:
IsInitialized(): Can't serialize message of type "XXX" because it is
missing required fields: YY, ZZ
unknown file: Failure
C++ exception with description "CHECK failed: IsInitialized(): Can't
serialize message of type "XXX" because it is missing required fields:
YY, ZZ" thrown in the test body.
message_lite.cc的source code全部包含“GOOGLE_DCHECK”或“InitializationErrorMessage”......
我的应用程序不允许这样的异常停止程序(不确定C ++中的术语是什么,但基本上没有UncheckedExceptions),所以我真的需要一种方法来捕获这些,记录错误,并优雅地返回,以防一些消息严重损坏。无论如何这样做?为什么我看到this post表示某种google::protobuf::FatalException
,但我找不到它周围的文档(只有FatalException可能还不够)。
谢谢!
答案 0 :(得分:8)
您看到的失败表明您的程序中存在错误 - 程序已请求序列化邮件,而不是先填写所有必填字段。把它想象成一个分段错误。您不应该尝试捕获此异常 - 您应该修改您的应用程序,以便从一开始就不会发生异常。
请注意,检查是DCHECK
,这意味着它只在调试版本中检查。在发布版本中(定义{{1}}时),将跳过此检查,即使消息无效,也会写入消息。因此,只有在调试时,您才不必担心这会使您的应用程序在生产中崩溃。
(从技术上讲,你可以捕获NDEBUG
,但Protobuf代码原本并不是设计为异常安全的。最初,检查失败只会中止程序。看起来最近添加了google::protobuf::FatalException
,但由于代码不是异常安全的,因此在FatalException
被抛出的任何时候都可能会出现内存泄漏。所以,您可能应该像FatalException
那样对待它。)
答案 1 :(得分:0)
我解决了 我的问题和你一样。 如果在您进行序列化时另一个线程更改了原型项的大小,则抛出 FatalException 然后我首先将其复制到另一个原型项目中,然后将其序列化。
ProtoInput item; // it is global object
.
.
.
fstream output("myfile",
ios::out | ios::trunc | ios::binary);
ProtoInput in;
in.CopyFrom(item);
size_t size = in.ByteSizeLong();
void *buffer = malloc(size);
if (in.SerializeToArray(buffer, size) == true) {
output.write((char *) buffer, size);
}
output.close();
free(buffer);