iam*_*ind 5 c++ cross-platform compiler-errors protocol-buffers static-linking
在所有编译器(g++/Linux、clang/Mac、msvc/Windows)的 protobuf 设置中看到一个奇怪的问题。这是它的最小形式:
message A { // declare objA
int32 i;
}
message B { // declare objB
string s;
repeated bytes rb;
}
...
objA.CopyFrom(objB); // No compiler error?!
Run Code Online (Sandbox Code Playgroud)
我预计CopyFrom()(或MergeFrom()) 会出现编译器错误,例如“没有匹配的函数调用...”。但它在所有环境下都可以正常工作!.pb.h 中方法的声明看起来不错。它只需要类型A。但它会给其他非 protobuf 类型带来编译器错误。
这是某种错误吗?
为什么 protobuf CopyFrom() 和 MergeFrom() 适用于每种消息类型?
CopyFrom因为and有一个重载版本MergeFrom:
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
Run Code Online (Sandbox Code Playgroud)
由于B是从 派生的Message,因此没有编译器错误。
但是,如果您尝试复制或合并两种不同的类型,运行时检查将失败,并引发异常。
[libprotobuf FATAL protobuf/src/google/protobuf/reflection_ops.cc:74] CHECK failed: (to->GetDescriptor()) == (descriptor): Tried to merge messages of different types (merge B to A)
libc++abi: terminating with uncaught exception of type google::protobuf::FatalException: CHECK failed: (to->GetDescriptor()) == (descriptor): Tried to merge messages of different types (merge B to A)
Abort trap: 6
Run Code Online (Sandbox Code Playgroud)
为什么存在这些过载?
因为你可以使用protobuf反射来动态创建一个Message其真实类型为A(反射接口返回基类,即Message,而不是真实类型)。在这种情况下,您可以使用这些重载从动态生成的Message.
| 归档时间: |
|
| 查看次数: |
3829 次 |
| 最近记录: |