1

我目前正在开发一个 DLL,它是一个封闭的、正在运行的项目的扩展。

我想捕捉每一个纯调用错误,所以我用谷歌搜索并发现了 _purecall 处理程序。我的问题是关于它的实施。幕后发生了什么?编译器本身获取我的处理函数地址(如果我定义了一个)并将其写入 v-table 中的每一行的默认值,然后它被类函数地址本身覆盖(在初始化之后),或者它更复杂,涉及CRT 和全局指针?

我问这个是因为我当然不希望我的插件 DLL 覆盖整个应用程序 _purecall 处理程序。我可以确定我的 purecall 处理程序将只处理我的模块中的 purecall 吗?

谢谢!

4

1 回答 1

1

答案很大程度上取决于您的编译器如何实现 purecall 处理程序。如果编译器只是替换了虚函数表中的“纯”函数指针,那么您就可以安全地修改父进程的行为。

但是一些编译器通过从 CRT 的处理程序调用您的处理程序来实现自定义的纯调用处理程序。在这种情况下,行为将取决于您构建 DLL 的方式。如果您已静态链接到 CRT,那么您的 DLL 将拥有自己的所有 CRT 状态的实例。在这种情况下,编译器实现无关紧要。您的 purecall 处理程序不会干扰父进程。

另一方面,如果您已动态链接到 CRT,则行为将取决于宿主进程的构建方式。如果它与您的 DLL 动态链接到相同版本的 CRT,那么您的 purecall 处理程序确实可能会干扰。但是再一次,这取决于编译器的实现。即使它从 CRT 调用你的钩子,如果 CRT 为每个模块维护不同的钩子,你也可以是安全的。

在任何情况下,如果您想确保安全,则必须将 DLL 静态链接到 CRT 或避免使用 purecall 处理程序(另一种方法是使用具体基类而不是抽象基类)。

于 2011-03-18T19:19:37.787 回答