从构造函数跨 DLL 边界抛出异常

Throwing exception from constructor across DLL boundary

有几个关于从构造函数抛出和跨 DLL 边界抛出的问题,但我找不到可以回答这一特定情况的问题。

我读过的两件事:

  1. 如果发生不好的事情,构造函数应该抛出异常。这确保了对象不会处于僵尸状态,不再需要函数来检查对象的状态,并强制执行 RAII。一切美好。

  2. 我们不应该跨越 DLL 边界。堆内存不共享,可能会发生坏事。这个细节让我有点逃避,但到处都是一般的建议是不要这样做,所以我不会。这里的例外 (!) 是当所有代码都使用相同的编译器编译时,但即使那样似乎也是特定于编译器的,因此并不可靠。是错误代码!

现在我的问题是:

如何安全地创建在 DLL 某处定义的 class 实例?

我认为也许唯一安全的方法是让 DLL 中的所有(导出的)构造函数承诺不抛出异常,或者提供导出的自由函数,return如果捕获到异常,该对象可能为 NULL。

任何人都可以提出更合适的建议,或者告诉我我的做法不对吗?

我认为你的方法是正确的。让我们为对象而不是对象本身导出工厂。

顺便说一句,它可以被投影,这样对于您的每个 DLL,您都可以拥有一个同名的导出函数。因此,在该导出函数中,您可以使用 if-else 块枚举 DLL 的所有工厂并尝试构造请求的对象。 (假设,对象由名称、名称的 crc32、名称的哈希值等标识)

我认为这里可能有几种方法。 例如,您可以在 DLLMain/Attach 事件的公共对象上注册每个 DLL 工厂,而不是公共导出函数,或者处理自定义 DLLMain 事件 - 您自己的 - 这样您就可以将 Neo 对象地址作为参数到 DLLMain 并为每个 DLL 在其上注册确切的工厂。

但常见的事情是当您的对象可能对 ctor/init 方法提出期望时使用工厂。