一、存储结构:

初始化单元存储在一个数组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中;其他单元依次处理;

Delphi 初始化的顺序的更多相关文章

  1. Java程序初始化的顺序

    Java程序初始化的顺序 java程序初始化工作可以在许多不同的代码块中来完成(例如:静态代码块.构造函数等),他们执行的顺序如下: 父类静态变量 父类静态代码块 子类静态变量 子类静态代码块 父类非 ...

  2. Java的初始化执行顺序(父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数)

    1. 引言 了解Java初始化的顺序,有助于理解Java的初始化机制和内存机制. 顺序:父类static变量->子类static变量->父类成员变量->父类构造器->成员变量- ...

  3. C++复习14 构造函数初始化调用顺序

    1.关于构造函数初始化调用顺序的问题. 首先是父类和子类的,首先调用父类的构造函数,然后调用子类的构造函数.但是对于子类中有其他类型的数据成员的时候,会在调用该类的构造函数之前,调用其数据成员的构造函 ...

  4. 八、 Java程序初始化的顺序(一)

    今天在写构造器方法的时候,遇到了一个小问题,由这个问题引发了一连串的思考,在一个Java类中变量与类的初始化执行顺序是什么样的呢?## 发现问题 class Student{ private Stri ...

  5. c++中初始化列表的初始化变量顺序问题

    例题来看:请问下面程序打印出的结果是什么? #include <iostream> #include <string> using namespace std; class b ...

  6. 关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例(在Delphi 初始化每一个TWinControl 对象时,将会在窗体 的属性(PropData)中加入一些标志,DLL的HInstance的值与HOST 进程的HInstance并不一致)

    建议先参考我上次写的博文跨进程获取Richedit中Text: 获得QQ聊天输入框中的内容 拿到这个问题,我习惯性地会从VCL内核开始分析.找到TRichEdit声明的单元,分析TRichEdit保存 ...

  7. 关于java中构造方法、实例初始化、静态初始化执行顺序

    在Java笔试中,构造方法.实例初始化.静态初始化执行顺序,是一个经常被考察的知识点. 像下面的这道题(刚刚刷题做到,虽然做对了,但是还是想整理一下) 运行下面的代码,输出的结果是... class ...

  8. Java中程序初始化的顺序

    1,在一个类的内部(不考虑它是另一个类的派生类):很多人认为,类的成员变量是在构造方法调用之后再初始化的,先不考虑这种观点的正确性,先看一下下面的代码: class Test01...{ public ...

  9. C++类几种初始化的顺序

    首先给段代码: class A{ public: ; A():x(){cout<<"A(): x="<<x<<endl;} A(int a):x ...

随机推荐

  1. java基础学习之单例设计模式学习

    最近狂补java基础的我重新学习了下单例,下面直接贴出代码,以作备忘 package com.darling.single; /** * 单例模式 * 单例即在内存中只存在该类的一个实例,要想实现这个 ...

  2. 2019.3.5 L261 Are All Our Organs Vital?

    Medicine has not always shown a lot of respect for the human body. Just think about the ghoulish dis ...

  3. L253 Work and Pleasure

    To be really happy and really safe, one ought to have at least two or three hobbies, and they must a ...

  4. php优秀框架codeigniter学习系列——common.php

    文件位于system/core/common.php,是框架核心文件. 该文件中定义了一系列的函数,都是框架运行中经常需要用到的.下面逐一介绍. is_php /** * Determines if ...

  5. python redis操作数据库方法

    Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

  6. python 爬虫数据准换时间格式

    timeStamp = 1381419600 dateArray = datetime.datetime.utcfromtimestamp(timeStamp) otherStyleTime = da ...

  7. 你知道怎么用Idea抽取方法、创建class吗?

    liJ IDEA的快捷键是进行重构的利器,坊间盛传,完全使用IDEA快捷键重构的代码,是不需要写测试用例保护的 本文就分享一个使用IDEA抽取方法及创建新的class的方法 工具/原料   Intel ...

  8. python day09作业

  9. vuejs 1.x与2.x差异

    1.x与2.x区别 v-for列表查询中 当前下标:$index --> index 1.x 用法 v-for="v in myData" =>$index获取下标 / ...

  10. 使用json通过telegraf生成metrics(摘自telegraf github文档)

    JSON: The JSON data format flattens JSON into metric fields. NOTE: Only numerical values are convert ...