通过 DLL/SO 边界传递异常 [英] Passing exceptions through DLL/SO boundaries

查看:138
本文介绍了通过 DLL/SO 边界传递异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到编译器功能,如果共享库使用不同于可执行文件的标准库的标准库编译,则加载共享库.我知道标准库的ABI 没有标准化,但我可以使用自己的基类来处理所有异常.

我发现异常处理 ABI 在 Linux 上标准化(安腾 C++ ABI:异常处理),和在 Windows 上(x64 异常处理).

据我所知,数据对齐也标准化了(System V 应用二进制接口 AMD64 架构处理器补充x64 软件约定).

  • 目标架构:amd64AArch64
  • 目标平台:LinuxWindows.

我可以使用异常还是需要在 DLL/SO 边界处理它们?

如果可执行文件和共享库使用不同的编译器(MSVCGCCGCCMSVC),我可以使用异常吗?> 分别)

解决方案

跨使用同一工具集的不同版本编译的模块边界使用异常甚至不一定安全.

例如,您的异常类型可能有一个 std::string 成员,但 std::string 从一个标准库版本到另一个版本的实现方式可能大不相同.如果您的库模块是使用旧工具集编译的,但客户端程序使用较新版本,则异常将填充与旧实现匹配的对象,但程序将尝试访问它,就好像它是新实现一样.

老实说,这适用于几乎所有 C++ 非 POD 类型,而不仅仅是例外.可以跨库边界使用 C++ 对象,但通常只有使用相同的工具和标准库编译和链接所有代码.例如,这就是为什么 MSVC 的所有主要版本都有 boost 二进制文件的原因.

我想您可能能够避免抛出不是从 std::exception 派生的 POD 异常类型,但这会非常有限(例如,它需要捕获确切的类型).

I am trying to find compiler features which will work if shared library compiled using standard library that differ from standard library of executable, that load shared lib. I understand that ABI of standard library is standardized nowhere, but I can use my own base class for all exceptions.

I found that exception handling ABI standardized on Linux (Itanium C++ ABI: Exception Handling), and on Windows (x64 exception handling).

Also as I understand data alignment standardized too (System V Application Binary Interface AMD64 Architecture Processor Supplement, x64 software conventions).

  • Target architectures: amd64, AArch64;
  • Target platforms: Linux, Windows.

Can I use exceptions or I need to handle them at the DLL/SO boundaries?

Can I use exceptions if executable and shared library use different compilers (MSVC and GCC or GCC and MSVC respectively)

解决方案

It is not necessarily even safe to use exceptions across boundaries of modules compiled with different versions of the same tool-set.

For example, your exception type may have a std::string member but std::string can be implemented very differently from one standard library version to another. If your library module were compiled with an old tool-set but the client program with a newer version the exception would be populated with objects that match the old implementation but the program would then try accessing it as if it were the new implementation.

Honestly, this is true for pretty much all C++ non-POD types, not just exceptions. It is possible to use C++ objects across library boundaries but generally only so long as all of the code is compiled and linked using the same tools and standard libraries. This is why, for example, there are boost binaries for all of the major versions of MSVC.

I suppose you might be able to get away with throwing a POD exception type that is not derived from std::exception but that would be very limited (for example it would require catching the exact type).

这篇关于通过 DLL/SO 边界传递异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆