2010-12-19 40 views
4

我正在编写一个使用外部第三方C库的C++库。所以我的图书馆会在这个第三方库中调用函数,第三方库会回调到我的库的不同部分。外部链接C库中的异常传播

我想知道在这种情况下异常会发生什么? 说MyLib :: foo()调用最终调用MyLib :: bar()的外部C库函数,并且bar会引发异常,会发生什么情况?异常是否会正确传播到foo()中的处理程序?

谢谢!

回答

6

将例外正确传播给foo()中的处理程序吗?

我想通过外部C代码传播的异常是未定义的。更糟糕的是,C代码没有做好准备,无法处理异常。 C代码不需要免于突然意外的回报,所以它不知道RAII等。

当我遇到过这种情况时,在返回C API之前,我发现了异常,并保存了它,在C API调用回来后重新抛出它。

+2

这比我的回答要好。我没有看到第三方库是C而不是C++。尽管提问者多次提到这一点。睡前,也许。 – 2010-12-19 22:21:14

+0

这是正确的答案。尽管有些实现(GNU)竭尽全力试图允许异常在C代码中传播,但这是一个非常糟糕的想法。它不仅不可移植,而且没有理由假设其间的C代码不会存在不一致的状态,或者持有尚未从外部记录或释放的内存分配。最好你要求内存泄漏,最坏的情况是随机崩溃。我喜欢sbi关于如何解决这个问题的建议,但最好避免在模块边界抛出异常。 – 2010-12-20 01:54:00

+1

@Tommy:我写了冗长的解释,为什么让异常通过C库传播是不好的,作为对你的回答的评论,并且当我想提交评论时已经删除它,变得脾气暴躁。所以感谢你的评论,这是弥补了这一点。 ':)' – sbi 2010-12-20 09:06:43

1

这是一个沉重的平台实施细节。一般来说,异常管道有可能通过C函数激活帧来展开堆栈。因为CRT通常是用C编写的,所以必须这样做。然而,C代码不太可能为它感到高兴,状态发生了变化,无法恢复。为了防止这是Windows,C代码确实有一个镜头。 C++异常支持内置于Windows的通用异常支持,称为结构化异常处理(SEH)。您可以使用__try和__except关键字来调用可以恢复C代码状态的异常过滤器。显然这不是便携式的。

请不要询问实施细节问题,不要提及实施细节。