关于运行时包的三个问题 (300分)

  • 主题发起人 主题发起人 blue_morning
  • 开始时间 开始时间
B

blue_morning

Unregistered / Unconfirmed
GUEST, unregistred user!
一、为什么Delphi写的程序(exe和dll,Exe主程序根据菜单的点击动态的载入各个功能Dll)当exe向dll中传递了TScreen对象时就一定要使用运行时包进行编译?
二、另外如果使用运行时包编译的dll中使用了raise Exception('不要乱整')语句(目的是我要在Appliction.OnException事件统一的处理异常,而Application控件放在exe的MainForm中),异常可以被捕获但exe主程序不确定的会在退出后出rtl60.bpl的AV异常?!这个问题整得我头晕得很啊。我现在改成了这样写
begin
Application.MessageBox('不要乱整','提示');
Exit;
end;
这样写rtbl60倒是牢骚少了,但是一句语句就变成了4句语句。如何办?
三、我如何知道使用运行时包编译程序发布时需要那些Delphi的运行时包,我看我的Project的运行时包编译包的列表中居然包含:webdsnap、websnap、soaprtl、dbexpress
、dbxcds、indy、dclOffice2k这样的包,这些包和我的程序是没有任何关系。Delphi不会这么搞笑吧?
 
1、使用运行时包,解决了在Exe和DLL调用类创建实例是确保相同。
2、
3、你只要将使用的包写在这就可以了,不使用的不写也没关系,delphi缺省将所有注册的包都列在这了。
 
一、(DLL和EXE同时)使用运行时包,可以确保两者的全局变量是相同的。所以象Application,Screen等程序运行就生成的全局变量(其实还不止这些)在内存中其实是同一样东西。这样的好处有1:节省内存;2:类结构确保一致,所以直接使用RTTI比如is、as操作符;3:DLL接口调用可以直接使用程序中自定义的数据结构,不必是标准win32结构也不会在调用上出错
二、DLL和EXE同时使用运行时包,应该不会出现这个问题呀。我怀疑是你的代码中的异常控制逻辑与你使用exit的逻辑是不一样的,这个要具体问题具体分析。比如可能是使用raise时,因为异常会一直向上层抛,而exit只是退出当前函数,所以有些资源释放的代码执行顺序就变了
三、要知道这个很简单,使用EXESCOPE实用程序,或Visual Stadio等工具,最简单就是:
tdump 执行文件名 > exeinfo.txt,打开exeinfo.txt看其中的"Imports from",看看到底有多少个bpl,就是程序实际使用的包了
至于delphi把包全列上,只是为了方便使用起见,这样可以保证编译出来的程序最小,而且没用到的,也不会链接进去的,你可以放心。
要控制只发布使用哪些包,只要修改这个列表即可,要带哪个包发布,就写上哪个包。
 
回过了。
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=2515069
 
我把aimingoo在其它帖子的回复一同粘过来了:
to blue_morning,
1. 并不是“传递了TScreen对象时就一定要使用运行时包”,而是“传递了对象就一定要
使用运行时包”。对象实例使用堆分配,也就是使用GetMem()来分配内存,因此它要求在
包(或)DLL之间使用同一个内存管理器。使用同一个内存管理器的常见方法是用“运行期
包”。当然,你也可以使用共享内存管理器单元。
2. 这个问题我不能很确定原因。但可以提示的一点是,如果你使用这种方法来构建APP,
那么可能会出现这样的情况(关闭程序时的次序):
1). 应用程序退出
2). 主程序(EXE)退出, 但进程空间不释放
3). 各模块(DLL/BPL)退出, 如果退出中异常, 将调用到EXE中的异常处理代码, 又由
于EXE已经退出, 因此可能导致出错
4). 进程空间释放
由于主进程的退出代码(单元结束化)已经全部执行过,所以等到DLL中发出异常时,EXE
模块中的Application对象其实已经Free过了。
——上面的结论是:如果退出过程中DLL发出异常,将无法处理而导致系统出错。
3. 查看菜单“//Project/Options/Packages”,调整“Build With Runtime Packages”
的列表中的包名。通常情况下,你只需要"vcl;rtl"即可。你在这里添加的其它包中,如
果引用了更多的包,实际上也是编译发布的”。你可以用一些工具来查看程序运行期实际
载入的包列表,例如可以用listdlls.exe这个小程序。
http://www.sysinternals.com/ntw2k/freeware/listdlls.shtml
 
to: aimingoo
问题1、如果我不传递TScreen,只传递Application就可以不使用运行时包编译程序并且程序的运行是正常的。所以我才这样问.
to All
对于问题2,我再研究看看但目前我决定不再使用Exe中的Application.OnException来处理Dll中的异常。这可能是自找麻烦。因为如果分开考虑,那么Dll这种期望别人来处理的思想不合适用在这种结构中。
多谢大家。
 
后退
顶部