Protocol Buffers C++ 中的异常处理

Exception handling in Protocol Buffers C++

我在 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),所以我真的需要一种方法来捕获这些异常、记录错误和 return 优雅地,以防某些消息被严重损坏。反正有这样做吗?为什么我看到 this post 表示某种 google::protobuf::FatalException 但我找不到关于它的文档(只有 FatalException 可能还不够)。

谢谢!

您看到的失败表明您的程序中存在错误 -- 该程序已请求序列化一条消息,而没有先填写所有必填字段。将其视为分段错误。您不应该尝试捕获此异常 - 您应该修复您的应用程序,以便异常永远不会首先发生。

请注意检查是 DCHECK,这意味着它仅在调试版本中检查。在您的发布版本中(定义 NDEBUG 时),将跳过此检查并写入消息,即使它无效。因此,您不必担心这会使您的应用程序在生产环境中崩溃,只需在调试时即可。

(技术上你可以捕获 google::protobuf::FatalException,但 Protobuf 代码最初并不是设计为异常安全的。最初,检查失败只会中止程序。看起来 FatalException 被添加最近,但由于代码不是异常安全的,所以每次抛出 FatalException 时都可能会发生内存泄漏。因此,您可能应该将其视为 abort()。)

我解决了 我的问题和你一样。 如果在您进行序列化时另一个线程更改了原型项的大小,则抛出 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);