zoukankan      html  css  js  c++  java
  • Delphi 初始化的顺序

    一、存储结构:

    初始化单元存储在一个数组InitContext.InitTable^.UnitInfo中,其中UnitInfo是以数组的方式存储的,其中InitTable的定义为:

    其中InitTable定义为packageInfo的类型,再来看看PackageInfo的定义:

    可以看到PackageInfo中的UnitInfo被定义为PUnitEntryTable类型,接下来再看PUnitEntryTable的定义:

    可以看到单元例程存储在一个数组中,最大可以存储一千万个单元例程,每个例程函数中有Init和FInit两个入口函数,其中Init表示Initialization例程的入口地址,FInit为Finalization例程的入口地址;

    结论:delphi初始化例程函数是以一个顺序列表的方式存储的;

     

    二、初始化例程执行顺序:

             初始化例程执行函数在System.pas单元的InitUnits函数中:

    结论:初始化执行是一个顺序循环执行过程,从0到Count – 1的顺序执行;

             Finalization例程的执行是在System.pas单元的FinalizeUnits函数中:

    结论:Finalization执行是一个逆序循环执行过程,从Count - 1到0的逆序执行;

    三、初始化例程搜索顺序:

             单元例程的搜索顺序是编译器完成,无法看到代码,但是可以写一些小的Demo来猜测其搜索顺序;

             如果在dpr中引用了Unit1,然后又在Unit1中引用了Unit2,接着在Unit2中引用了Unit3,那么在执行Initialization时先执行Unit3,再是Unit2,最后是Unit1;

             如果在dpr中顺序引用Unit1, Unit2, Unit3,但是在Unit1中不引用Unit2,Unit2中不引用Unit3,那么在执行Initialization时先执行Unit1,再是Unit2,最后是Unit3;

    结论:首先从dpr文件中加载第一个单元如A,在试图加载A的Initialization时,先查看A的uses部分,这里的uses不分Interface部分还是implementation部分,只分先后顺序,当发现A有Uses单元时,比如依次引用了单元B和C,则先将A压入堆栈,然后处理B,如果B引用了其他单元,处理方式同A,如果没有引用其他单元,则将B的例程保存到UnitEntryTable中(如果UnitEntryTable中已经有了B单元则不保存);接着以相同的方式处理C,当A引用的单元都处理完后将A从堆栈弹出并保存到UnitEntryTable中;其他单元依次处理;

  • 相关阅读:
    教育后台管理系统:Postman
    教育后台管理系统:查询课程列表信息
    教育后台管理系统:JSON
    教育后台管理系统:后台系统搭建
    教育后台管理系统:Maven的常用命令 & 依赖范围
    教育后台管理系统:Maven 项目管理工具
    教育后台管理系统:项目架构
    Vocabulary:annexation
    Java Web(二)- 学习笔记
    Listener监听器 -案例
  • 原文地址:https://www.cnblogs.com/laoxia/p/4218218.html
Copyright © 2011-2022 走看看