如何用我自己的方法可靠地替换库定义的错误处理程序?

时间:2010-03-18 07:37:09

标签: c++ visual-c++ com linker atl

在某些错误情况下,ATL调用AtlThrow()ATL::AtlThrowImpl()实现为CAtlException,而std::exception则会CAtlException。后者不是很好 - CAtlException甚至不是从ATL::AtlThrowImpl()派生出来的,我们也使用自己的异常层次结构,现在我们必须在这里和那里分别捕获_ATL_CUSTOM_THROW额外的代码和容易出错的。

看起来可以用我自己的处理程序替换AtlThrow() - 定义atlbase.h并在包含atls.lib之前将ATL::ThrowImpl()定义为自定义处理程序 - 并且ATL将调用自定义处理程序。

不那么容易。一些ATL代码不在源代码中 - 它被编译为库 - 静态或动态。我们使用静态 - ATL::AtlThrowImpl()。而且......它的编译方式是内部有ATL::AtlThrowImpl(),有些代码调用它。我使用了一个静态分析工具 - 它清楚地显示了调用旧的默认处理程序的路径。

确保我甚至尝试在代码中“重新实现”{{1}}。现在链接器说它看到{{1}}的两个声明,我想这证实了某些代码可以调用另一个实现。

我该如何处理?如何完全替换默认处理程序并确保永远不会调用默认处理程序?

2 个答案:

答案 0 :(得分:1)

我在编写自己的内存管理器时遇到了类似的问题,想要推翻malloc和free。

问题是ATL :: AtlThrowImpl可能是源文件的一部分,该文件还包含其他真正需要的文件。

如果链接器在其中一个目标文件中看到对函数的引用,则它会使用该函数提取目标文件,包括该同一目标文件中的所有其他函数。

解决方案是查找定义了ATL :: AtlThrowImpl的ATL源,并查看源是否包含其他函数。您还需要实现其他函数以防止链接器对原始ATL源有任何引用。

答案 1 :(得分:1)

我在很长一段时间内没有使用过这些windows库,但是你应该能够让链接器通过将它放在链接语句前面列出的静态库中来选择替换。确保使用与原始方法相同的方法签名。对于各种默认定义,您还可以使用链接器标志来省略默认库。

如果你的朋友可以访问MSDN,它可能有一些ATL调试源,这也有帮助。

而且,正如帕特里克所说,你需要为同一个联动范围内的所有东西提供替代品。有些库将各个方法分解为单独的目标文件,以便更换一个。这种情况在例如c标准lib比一类。如果有很多ATL代码能够在单个目标文件中调用它们的throw impl,那么它可能会比它更值得痛苦....你可能需要尝试捕获并重新抛出你自己的类型。