扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:soobey 来源:blog.csdn.net/soobey 2007年9月15日
关键字: 软件
现在我们看到,package工程的入口dpr文件结构中没有uses子句,但是取而代之的是contains子句。从字面上说,这好像是指明这个包将会由哪些Unit组成。这些Unit再去use别的unit,这样就又形成了一张有向图。是这样的吗?我们将Package1的contain部分改成
contains
UnitForm1 in 'UnitForm1.pas' {Form1};
这样仅包含UnitForm1。而UnitForm1中因为存在继承关系,必然要use UnitFormAnother。于是自然package1中必须包含三个Unit:Package1.dpk、UnitFormAnother.pas、UnitForm1.pas。然后编译,结果报警说:隐式地引入了UnitFormAnother。先不管这个警告,然后改exe工程:把FormMain的button1Click改成
procedure TFormMain.Button1Click(Sender: TObject);
var
LForm:TForm1;
begin
LForm:=TForm1.Create(Application);
LForm.ShowModal;
LForm.Free;
end;
当然,还要在FormMain的Uses里面加上UnitForm1,然后修改runtime package列表,加上package1。然后编译,调试,检查Module情况。结果发现ProjectExe里面包含FormMain,而Package1.pbl里面包含我们所推测的三个Unit。另一个试验是,如果在编译exe的时候,去掉列表中的package1,并且恰好能让编译器找到FormAnother和Form1(源文件也好,dcu也好),也可以成功编译。但是此时三个Form都跑到exe中间去了。
类似地,验证package2,发现:package2也可以编译过,前提是它能够找到FormAnother,此时package2中包含两个Form;如果把package2的require部分改成只依赖package1,那么最终编译出来的package2中则只含Form2。如果两个package都包含FormAnother,而exe同时使用两个package的话,那么会产生编译错误。(是啊,两个package同时加载一个类,当我要使用的时候,到底是谁提供服务呢?)这种情况很容易发生,因为一方面FormAnother是Form1和Form2的公共基类;另一方面,在Contain子句里面很容易不小心漏掉FormAnother。所以编译器的提示还是很不错的,写程序还是按规矩办事,把contain写完整比较好。
因此,现在基本可以得到结论:
现在,编译和连接的问题基本解决了,现在来研究加载。加载有两种,一种是自动的,由delphi控制;一种是手动的,在程序中写LoadPackage。先来搞清楚什么情况下会自动加载library。
测试是这样的,ProjectExe use UnitForm1, Package2 contains UnitForm2 requires package1,package1 contains UnitForm1和UnitFormAnother。在ProjectExe的Package list里面仅有package2。运行结果是:加载的包有rtl、vcl和package1,package2并没有出现。也就是说,自动装入内存的包是那些存在于A集合中,且跟B集合有交集的包。所有想要完全手工加载包,还必须要注意一些问题,起码它不能直接和间接地被require,包中的Unit也不能在Use里面出现。换句话说,调用者完全不知道被调用包的情况下才能避免自动装载。
既然调用者完全不知道被调用的包的信息,凭什么去调用呢?Delphi里面似乎没有头文件之类的东西。怎么获取这个包的接口呢?
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者