设为首页 加入收藏

TOP

11.4.2 MSVC CRT的全局构造和析构(2)
2013-10-07 00:44:26 来源: 作者: 【 】 浏览:52
Tags:11.4.2 MSVC CRT 全局 构造

11.4.2  MSVC CRT的全局构造和析构(2)

运行这个程序,可以得到如"hello"的输出。为了验证A~Z的这个字母表排列,读者可以修改SECNAME,使之不处于.CRT$XCA和.CRT$XCZ之间,理论上不会得到任何输出。而如果将段名改为.CRT$XCV(V的字典序在U之后),那么foo函数将在main执行之后执行。

MSVC CRT 析构

最后来看看MSVC的全局析构的实现,在MSVC里,只需要在全局变量的定义位置上设置一个断点,就可以看到在.CRT$XC 中定义的全局初始化函数的内容。我们仍然使用本章一开头的HelloWorld来作为示例:

#include <iostream>
class HelloWorld
{
public:
HelloWorld() {std::cout << "hi\n";}
~HelloWorld(){std::cout << "bye\n";}
};
HelloWorld Hw;
int main()
{
return 0;   
}
这里在加粗的位置上设置断点。运行程序并中断之后查看反汇编可以得到初始化函数的内容:
011B1B70 mov eax,dword ptr [__imp_std::cout (11B2054h)] 
011B1B75 push offset string "hi\n" (11B2124h)
011B1B7A push eax 
011B1B7B call std::operator<<<std::char_traits<char> > (11B1140h)
011B1B80 push offset `dynamic atexit destructor for 'Hw'' (11B1B90h)
011B1B85 call atexit (11B13B0h)
011B1B8A add esp,0Ch
011B1B8D ret
在这里可以看见这段程序首先调用了内联之后的HelloWorld的构造函数,然后和g++相同,调用atexit将一个名为dynamic atexit destructor for 'Hw''的函数注册给程序退出时调用。而这个dynamic atexit destructor for 'Hw''函数的定义也能很容易找到:
`dynamic atexit destructor for 'Hw'':
011B1B90 mov eax,dword ptr [__imp_std::cout (11B2054h)]
011B1B95 push  offset string "bye\n" (11B2128h)
011B1B9A push eax 
011B1B9B call std::operator<<<std::char_traits<char> > (11B1140h)
011B1BA0 add esp,8
011B1BA3 ret
可以看出,这个函数的作用就是在对象Hw调用内联之后进行析构。看到这里,我想各位读者肯定有跟我一样的心情,那就是希望举一反三的愿望并不是不切实际的,它是实实在在存在的。Glibc下通过__cxa_exit()向exit()函数注册全局析构函数;MSVC CRT也通过atexit()实现全局析构,它们除了函数命名不同之外几乎没有区别。
【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇11.3.3 线程局部存储实现(2) 下一篇1.5 fread实现

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: