您能否将同一个 protobuf 消息静态链接到多个 DLL 中,然后让这些 DLL 一起工作?

发布于 2024-08-22 15:41:44 字数 1155 浏览 4 评论 0原文

我们正在使用 google protobufs 在网络上传递数据。服务器端是类似插件的,因此处理 protobuf 消息的几个模块都是 DLL。一些 DLL 依赖于其他 DLL,并使用其他 DLL 的消息来定义自己的消息。

因此,A.DLL 有 a.proto,它生成带有消息类 MsgAa.pb.h/cc。使用协议编译器上未记录的dllexport_decl选项,消息类被声明为DLL导出。

现在,B.DLL 依赖于 A.DLL,而 b.proto 也如下所示:

import "a.proto";
message b 
{
    required int32 some_number = 1;
    required PackageA.MsgA some_a = 2;
}

最后,将各部分组合在一起的可执行文件也依赖于消息 MsgA。 protobuf 库也被构建为 DLL 并链接到所有内容。这一切都构建并运行。

但是,光明势力要求我们减少 DLL 的分发!因此,我将模块 A(它只是许多其他插件 DLL 使用的消息和小实用程序的集合)构建为静态库而不是 DLL。 B.DLL 和可执行文件都链接到 A,一切都很好 - 到目前为止。

由于 A 是静态链接的,MsgA 在所有 DLL 和 EXE 中得到完全定义。没关系,因为生成的 C++ 代码中的所有静态数据都是 const。如果最终过程中有多个副本怎么办——所有副本都是相同的。

但是,当我运行新构建的进程时,libproto 抛出一个实际上有用的异常 - MsgA 的文件 ID 已存在于描述符映射中(或类似的东西)。换句话说,MsgA 有多个定义是一个主要问题。

所以,最后,问题是:

  • 如果我们静态链接 libproto 而不是将其用作 DLL,错误会消失吗?
  • MsgA 的多个定义分散在 DLL 中真的安全吗?

一旦我开始重建 protobuf 库,我可能会在几天内回答自己的第一点,但第二点超出了我目前的知识范围。我还希望得到一个快速的向上或向下的答案,这可能会省去重新编译原始库的麻烦。

We are using google protobufs to pass data around on the wire. The server side of things is plugin-like so several of the modules handling the protobuf messages are DLLs. Some DLLs depend on others and use the others' messages to define their own messages.

So, A.DLL has a.proto which generates a.pb.h/cc with a message class MsgA. Using the undocumented dllexport_decl option on the protoc compiler, the message class is declared as a DLL export.

Now, B.DLL depends on A.DLL, and b.proto also looks like this:

import "a.proto";
message b 
{
    required int32 some_number = 1;
    required PackageA.MsgA some_a = 2;
}

Finally, the executable that pulls the parts together also depends on the message MsgA. The protobuf library was also built as a DLL and is linked into everything. It all builds and runs.

But, there are Forces of Light which have demanded that we cut down on the DLL distribution! So, I built the module A (which is just a collection of messages and small utils that a lot of the other plugin DLLs use) as a static library instead of a DLL. B.DLL and the executable both link to A and everything is good - so far.

Since A is statically linked, MsgA gets fully defined in all the DLLs and the EXE. That's OK because all the static data in the generated C++ code is const. So what if there are multiple copies in the final process - all of the copies are identical.

But, when I run the newly built process, libproto throws an actually useful exception - MsgA's file ID already exists in the descriptor map (or something like that). In other words, the fact that there are multiple definitions for MsgA is a major problem.

So, finally, here is the question(s):

  • If we statically linked the libproto instead of using it as a DLL, would the error go away?
  • Is it really safe to have the multiple definitions of MsgA scattered throughout the DLLs?

The first point I can probably answer myself in a few days once I get around to rebuilding the protobuf libraries, but the second one is a little further beyond my current knowledge. I'm also hoping to get a quick up or down answer that may save me the trouble of recompiling the proto libs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

安稳善良 2024-08-29 15:41:44

我已经使用 protobuffers 通过网络进行 RPC(Google 也这样做 - 请参阅文档页面)。只要您对使用 proto 缓冲区的每个人都有类似的定义,一个定义就会愉快地反序列化由其他定义序列化的数据。事实上,只要您不重新分配标签号,旧版本的协议缓冲区定义就可以与新版本进行良好的交互(只要反序列化定义中的“必需”字段存在于流中,它将成功)。

希望有帮助。

I've used protobuffers for RPC across a network (Google does this too - see the documentation page). As long as you have a similar definition for everyone using the proto buffer, one definition will happily deserialize data serialized by other definitions. In fact, as long as you don't re-assign the tag numbers, older versions of the protocol buffer definition can interact with newer versions just fine (as long as "required" fields in the deserializing definition exist in the stream, it will succeed).

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文