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

3
有一些有关在构造函数中抛出异常以及跨DLL边界抛出异常的问题,但我找不到回答这个具体情况的答案。
我读过的两件事情是:
1. 如果发生错误,构造函数应该抛出异常。这可以确保对象不处于僵尸状态,消除了函数检查对象状态的需要,并实施了RAII。所有这些都是好事情。
2. 我们不应该跨DLL边界抛出异常。堆内存不共享,可能会发生糟糕的事情。这方面的细节逃脱了我一些,但是普遍建议是不要这么做,所以我也不会这样做。唯一的例外是,当所有代码都使用相同的编译器编译时,但即使如此,这似乎也是与编译器相关的,因此不可靠。错误代码就是了!
现在我的问题是:
如何安全地创建一个定义在DLL中的类的实例?
我认为也许唯一安全的方法是让DLL中的所有(导出)构造函数承诺不抛出异常,或者提供导出的自由函数,返回指向一个对象的指针,如果捕获到异常则该指针可以是NULL。
有人能提出更合适的建议吗?还是告诉我我弄错了?

你需要确保exe和dll都使用相同版本的运行时支持,并且它是dll版本而不是静态版本。 - Richard Critten
2
值得一读:如何在DLL中使用类?。回答了你几乎所有的问题,还有一些你还没有想到的。 - user4581301
我甚至不喜欢导出一个类,因为错误版本的dll可能会引起问题。但是,如果该类用于内部实现导出函数,那就可以了。上面的注释链接通过仅导出接口来避免这种情况。 - Kenny Ostrom
1个回答

1

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

顺便说一下,可以这样设计,对于每个DLL,您都可以拥有一个具有相同名称的导出函数。因此,在该导出函数中,您可以具有if-else块,该块枚举DLL的所有工厂并尝试构造请求的对象。(假设,对象通过名称、名称的crc32、名称的哈希等进行标识)

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

但共同的事情是在对象的构造函数/初始化方法抛出异常时使用工厂。


2
我已经编写了 DLL,提供了一个工厂函数来创建类对象,但仅提供指针作为句柄。类本身未导出,并且只能通过导出的函数来使用。 - Kenny Ostrom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接