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

C++ 如何用我自己的错误处理程序可靠地替换库定义的错误处理程序?,c++,visual-c++,com,linker,atl,C++,Visual C++,Com,Linker,Atl,在某些错误情况下,ATL将调用它,该调用被实现为ATL::AtlThrowImpl(),然后抛出。后者不是很好-CAtlException甚至不是从std::exception派生出来的,而且我们使用我们自己的异常层次结构,现在我们必须在这里和那里分别捕获CAtlException,这是大量额外的代码,并且容易出错 看起来可以用我自己的处理程序替换ATL::atlthrowmpl()-定义\u ATL\u CUSTOM\u THROW并在包含atlbase.h之前将AtlThrow()定义为自定

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

看起来可以用我自己的处理程序替换
ATL::atlthrowmpl()
-定义
\u ATL\u CUSTOM\u THROW
并在包含
atlbase.h
之前将
AtlThrow()
定义为自定义处理程序,ATL将调用自定义处理程序

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

为了确保我甚至尝试在代码中“重新实现”
ATL::AtlThrowImpl()
。现在链接器说它看到了两个声明
ATL::AtlThrowImpl()
,我想这证实了有另一个实现可以被某些代码调用


我该怎么办?如何完全替换默认处理程序并确保从不调用默认处理程序?

在编写自己的内存管理器时,我遇到了类似的问题,希望否决malloc和free

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

如果链接器在其中一个对象文件中看到对某个函数的引用,它将使用该函数拉入该对象文件,包括同一对象文件中的所有其他函数


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

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

如果您有一个可以访问MSDN的朋友,它可能有一些ATL调试源代码,这也很有帮助


而且,正如Patrick所说,您需要为相同链接范围内的所有内容提供替换。一些库将单个方法分解为单独的对象文件,以便更容易替换一个部分。这在c标准库中比在类中更常见。如果有很多ATL代码能够在单个对象文件中调用它们的throw impl,那么这可能会带来更多的痛苦……您可能需要尝试捕获并重新引用自己的类型。

您是对的,但问题在于AtlThrowImpl()是一个内联函数,这些函数是专门处理的-所以底线是当前ATL设计需要库重新编译来替换处理程序。当然,以这种方式重写内联方法是不可能的。我看不到任何解决方案,除了修改头并重新编译整个ATL库。