CRT初始化 (参考自MSDN)

本文深入探讨了CRT如何在原生代码中初始化全局状态。详细解释了CRT如何通过启动代码初始化库,调用全局初始化器,并最终调用用户提供的main函数。此外,还介绍了如何确定全局对象初始化的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CRTInitialization

ThistopicdescribeshowtheCRTinitializesglobalstatesinnativecode.

Bydefault,thelinkerincludestheCRTlibrary,whichprovidesitsownstartupcode.ThisstartupcodeinitializestheCRTlibrary,callsglobalinitializers,andthencallstheuser-providedmainfunctionforconsoleapplications.

InitializingaGlobalObject

Considerthefollowingcode:

int func(void)

{

    return 3;

}


int gi = func();


int main()

{

    return gi;

}


AccordingtotheC/C++standard,func()mustbecalledbeforemain()isexecuted.Butwhocallsit?

Onewaytodeterminethisistosetabreakpointinfunc(),debugtheapplication,

andexaminethestack.ThisispossiblebecausetheCRTsourcecodeisincludedwithVisualStudio.

Whenyoubrowsethefunctionsonthestack,youwillfindthattheCRTisloopingthroughalistoffunctionpointersandcallingeachoneasitencountersthem.Thesefunctionsareeithersimilartofunc()orconstructorsforclassinstances.

TheCRTobtainsthelistoffunctionpointersfromtheVisualC++compiler.Whenthecompilerseesaglobalinitializer,itgeneratesadynamicinitializerinthe.CRT$XCUsection(whereCRTisthesectionnameandXCUisthegroupname).Toobtainalistofthosedynamicinitializersrunthecommanddumpbin/allmain.obj,andthensearchthe.CRT$XCUsection(whenmain.cppiscompiledasaC++file,notaCfile).Itwillbesimilartothefollowing:

SECTION HEADER #6

.CRT$XCU name

       0 physical address

       0 virtual address

       4 size of raw data

     1F2 file pointer to raw data (000001F2 to 000001F5)

     1F6 file pointer to relocation table

       0 file pointer to line numbers

       1 number of relocations

       0 number of line numbers

40300040 flags

         Initialized Data

         4 byte align

         Read Only


RAW DATA #6

  00000000: 00 00 00 00                                      ....


RELOCATIONS #6

                                                Symbol    Symbol

 Offset    Type              Applied To         Index     Name

 --------  ----------------  -----------------  --------  ------

 00000000  DIR32                      00000000         C  ??__Egi@@YAXXZ (void __cdecl `dynamic initializer for 'gi''(void))


The CRT defines two pointers:

__xc_a in .CRT$XCA

__xc_z in .CRT$XCZ

Bothgroupsdonothaveanyothersymbolsdefinedexcept__xc_aand__xc_z.Now,whenthelinkerreadsvarious.CRTgroups,itcombinestheminonesectionandordersthemalphabetically.Thismeansthattheuserdefinedglobalinitializers(whichtheVisualC++compilerputsin.CRT$XCU)willalwayscomeafter.CRT$XCAandbefore.CRT$XCZ.

Thesectionwillresemblethefollowing:

.CRT$XCA

            __xc_a

.CRT$XCU

            Pointer to Global Initializer 1

            Pointer to Global Initializer 2

.CRT$XCZ

            __xc_z


So,theCRTlibraryusesboth__xc_aand__xc_ztodeterminethestartandendoftheglobalinitializerslistbecauseofthewayinwhichtheyarelaidoutinmemoryaftertheimageisloaded.

<!--EndFragment-->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值