【问题标题】:error_category mismatch in asio when used across dlls跨 dll 使用时 asio 中的 error_category 不匹配
【发布时间】:2021-08-21 16:06:39
【问题描述】:

当从另一个 dll 或可执行文件接收到 asio::error_code 值时,我在处理它们时遇到了问题。例如,我可以使用处理程序运行异步操作:

socket.async_receive([](const asio::error_code& errorCode)
{
    if (errorCode == asio::error::operation_aborted)
       return;
}

如果处理程序是在 dll 中创建的,并且 errorCode 是从另一个 dll 或可执行文件传递的,operator== 将返回 false,因为它们的 error_category 值不同。例如:

(gdb) info sym 0x55f1c0
asio::system_category()::instance in section .data of C:\dev\builds\UWCASdk\Debug-MinGW-w64\Sandbox\ServerL410F\bin\sb.ServerL410F.exe
(gdb) info sym 0x6f0420d0
asio::system_category()::instance in section .data of C:\dev\builds\UWCASdk\Debug-MinGW-w64\Sandbox\ServerL410F\bin\libproviders.protobuf.client_d.dll

显然,这两个实例是在不同的单元中定义的,我基本上有 ODR 违规。

instanceasio/impl/error_code.ipp 中定义:

const error_category& system_category()
{
  static detail::system_category instance;
  return instance;
}

ASIO 文档在处理错误时没有提到任何关于 error_cateegory 的内容 - 它只指定枚举值,因此使用 errorCode.value == asio::error::operation_aborted 似乎是一种有效的解决方法。但这仍然看起来很丑。

  • 是否可以按预期比较跨 dll 的错误(operator== 重载)?
  • 仅将errorCode.value() 与枚举进行比较是正常的还是预期的?

【问题讨论】:

    标签: c++ dll error-handling boost-asio asio


    【解决方案1】:

    这就是我对 comment 的意思

    尽管 boost::system::system_error 可能会引发问题

    问题是,错误类别是全局单例实例,具有对象标识(即通过地址比较是否相等)。

    您最终会在多个模块中获得多个实例。通常的解决方案是

    • 动态链接到 Boost System,因此所有库都使用相同的副本(但这有时会遇到初始化顺序问题)
    • 如果这不能解决问题,请确保所有模块实际加载相同的库(版本?)
    • 在最近的增强中,我认为可以选择完全仅使用标题构建增强系统。这可能涉及也可能不涉及新奇的 C++14 内联,我没有检查。

    如果一切都失败了,请自行翻译。有相关的问题可能会给你一些想法:


    仅将 errorCode.value() 与枚举进行比较是正常的还是预期的?

    不,不是。根据一些消息来源,Boost 以及标准库承诺将通用错误类别映射到标准的 errc - 所以你可以这样做,但你仍然必须弄清楚这是否是类别,所以对你的场景没有帮助.

    【讨论】:

    • 感谢您的回复。我实际上只使用非升压标头 asio。我想到了链接到同一个运行时的可能性,但问题是:error_category 实例化发生在 asio 标头中。预处理器没有定义控制流(至少我没有注意到),它会使用除 asio 头之外的东西。
    • 有一种方法可以通过定义预处理器变量think-async.com/Asio/asio-1.18.2/doc/asio/…将独立的asio编译为共享库我建议您将其添加到您的答案中
    猜你喜欢
    • 1970-01-01
    • 2014-10-13
    • 2011-10-07
    • 2019-03-19
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多