投掷 C++跨 DLL 边界的异常
我读过各种有关如何不应在一个 DLL 中分配堆内存并从该 DLL 外部释放它的文章。但是抛出一个只是临时的异常对象(就像大多数异常对象一样)怎么样?例如:
throw my_exception( args ); // temporary: no heap allocation
当异常对象在DLL外部被捕获时,该对象的析构函数最终将被执行,并且该对象的非堆内存将被回收。因为它不是堆内存,所以可以吗?
I've read various things about how one should not allocate heap memory in one DLL and deallocate it from outside that DLL. But what about throwing an exception object that is a just a temporary (as most exception objects are)? E.g.:
throw my_exception( args ); // temporary: no heap allocation
When the exception object is caught outside the DLL, the destructor for that object will eventually be executed and the non-heap memory for the object will be reclaimed. Is that OK since it's not heap memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这取决于内存的分配方式以及分配机制(“运行时”或“内存管理器”)是否在特定 DLL 和应用程序的其他部分之间共享。例如,根据详细信息,
throw new my_exception( args ); 也可能是有序的。
您可以对异常进行引用计数,以便它具有如何销毁其自己的实例(和拥有的内存)的内在知识。
使用
IMalloc
(参见 MSDN)进行实例分配和放置new
是另一种方式(之前调用OleInitialize
)...事实上,内存分配是一个问题,具体取决于所使用的内容。例如,在应用程序的不同部分混合静态链接的 CRT 和动态链接的 CRT 会导致问题,就像混合调试和发布代码一样。这里的问题是应该释放内存的代码使用不同的“内存管理器”。但是,如果抛出的对象知道它自己的销毁,那么应该没问题,因为 dtor 代码将驻留在与分配它的编译单元相同的编译单元中。
It depends how that memory was allocated and whether the mechanism to do so ("the runtime" or "memory manager") is shared between the specific DLL and the other parts of the application. E.g. a
throw new my_exception( args );
could also be in order depending on the details.You could make your exception reference counted, so that it comes with the intrinsic knowledge of how to destroy its own instance (and owned memory).
Using
IMalloc
(see MSDN) for instance allocation and placementnew
would be another way (callOleInitialize
before) ...Indeed, the memory allocation is an issue depending on what is being used. For example mixing statically linked CRT and dynamically linked CRT in different parts of an application will lead to issues the same way the mixing debug and release code would. The problem here is that the code that is supposed to free the memory uses a different "memory manager". But if the thrown object knows about its own destruction, it should be fine, since the dtor code would reside in the same compilation unit as the one allocating it.
仅当所有模块使用相同的 C++ 运行时时,才可能跨 DLL 边界抛出 C++ 异常,在这种情况下,它们也共享堆。但这可能会成为维护负担,特别是当涉及多个供应商的库时,因此不鼓励这样做。
如果您想要跨多个编译器/编译器版本/编译器设置移植的错误处理,请使用返回代码或操作系统提供的异常(例如 Windows 上的 SEH)/
Throwing C++ exceptions across DLL boundaries is only possible when all modules use the same C++ runtime, in which case they share a heap as well. But this can be a maintenance burden, especially when libraries from multiple vendors are involved, so it is discouraged.
If you want error-handling which is portable across multiple compilers/compiler versions/compiler settings, either use return codes or OS-provided exceptions (e.g. SEH on Windows)/