有没有可能做到:Build with runtime packages的时候只使用自己的包,其他的都是静态链接入EXE(300分)

X

xianjun

Unregistered / Unconfirmed
GUEST, unregistred user!
在我机器上(delphi6 update pack2 + win2k sp3),只要是选了Build with runtime packages
然后无论在Package列表里写什么,Build出来的程序都要用到rtl60.bpl及vcl60.bpl
如果用了其他控件的话还要其他的bpl。是我的delphi有问题还是本来就是这样??
怎么才能做到只用到我自己的BPL而不要Delphi自身的BPL(如rtl60.bpl, vcl60.bpl,vclx.bpl等)?
否则的话我岂不是要发布一大堆的BPL??
(可在没装Delphi的机器上测试或用memory sleuth监看EXE装载的BPL)
对Delphi的底层编译链接机制不太了解,哪位知道的或作过这方面研究的大侠还请指点一二。
 
呵呵,,这不是你的DELPHI的问题,,呵呵,,我想装了BORLAND公司的DELPHI的所有人的
情况和你一样的吧:)首先,我的是这样的,,,,
关于怎样抛弃DELPHI的BPL而用自己的,,我就不知道了,,我想那你就只有不用DELPHI了,
那就用PASCAL吧,,哈哈哈,,,其实BPL类似于微软的DLL,只不过名称不同罢了(我先申明:
至于BPL和DLL是否相同,我没研究过,但作用是类似的吧)

微软的东西还是一样的,他在操作系统里加了很多DLL,,,以给它的开发工具提供支持,
(就象MFC,在操作系统里就有好几十兆的 DLL 是给MFC提供的)
而BORLAND公司就没这么幸运了,,

不知道你是否用过 金山词霸?它就是用DELPHI开发的,它也需要你所说的那几个包的支持,
只不过放到了操作系统的 SYSTEM 系统目录中,,

如果有哪位高人知道怎么抛弃DELPHI的BPL而用自己的,麻烦给我讲一下,,万分感谢!!

 
你看看这样行不行, 编译时不要选Build with runtime packages, 然后动态加载
你的包?
 
bpl文件就是dll,只不过是Delphi程序专用的。你如果选择Build with runtime packages,
就必须安装需要的bpl文件,但同时你的exe文件就小多了,它的好处是当你在一台机器上
安装多个Delphi程序时提高效率。如果你不选择Build with runtime packages,所需要的
库都链接在你的exe文件中,如果有多个这样的exe的话,岂不是很浪费?
 
本来就这样!牺牲点程序的大小吧!
 
我的意思是这样:我可以为我的程序选择runtime packages,并不是说不要Delphi原有的BPL
比如说,我自己开发了一个runtime package,我想我的程序build with这个BPL,但我不
希望一定要把rtl60.bpl,vcl60.bpl等也加上(现在的情况就是这几个一定会跟进来),我
希望rtl60.bpl及vcl60.bpl等里的代码静态链接进入我的程序,只有我自己的bpl才动态链接。
Build with runtime packages下面不是有个框让人填哪些BPL吗? 现在的情况是无论填
什么效果都是一样,都需要rtl60.bpl等,这不是让人很奇怪吗???

to tseug:
这样动态加载的话,跟编写DLL的情况就没什么两样了。只有在Build with runtime packages
时才能有我要的效果: 我的BPL里各单元用RegisterClass注册的类在主程序里能用FindClass
找到。如果没有Build with runtime packages,即使你LoadPackage装载了自己的包,包里
面用RegisterClass注册的类在主程序里用FindClass也是找不到的。或者大家看看有没有办法
实现这个目的?

to HeyTommy:
BPL跟DLL应该是差不多的东西,但也不是完全一样,Delphi对它作了特殊处理:如DLL里的
全局变量对每一个用LoadLibrary进来的程序而言都是独立的,但BPL就不是了。具体描述你
可以看一下李维写的:《如何使用Delphi開發大型主從架構系統-Package的秘密和威力》
http://www2.borland.com.tw/tw/reference9.html

to bluebridge:
我现在的问题就是: 我能不能选择在客户机上需要安装的BPL文件?最理想的情况就是,
我只要安装我自己开发的运行时BPL,而Delphi自带的那些则静态链接到EXE中。
 
xianjun:
先感谢!
既然你要这样,那么你可以把你的写成DLL啊,而BPL你就不选生成BPL了塞,,,我想只又这样了
,如果你非要自己的动态加载的东西要是BPL,而DELPHI带的要静态连接进去,我想是不可能的了,

除非BORLAND 提供这样的功能!!
 
xianjun:

劳烦:
哪里有资料关于BPL的结构的?
 
HeyTommy:
BPL的结构Borland应该没有公开吧? 我没有见过有写这方面的文章
生成DLL的话就达不到我的目的了,我要在DLL里用RegisterClass注册我的类,然后在DLL
的调用程序中用FindClass根据类名取得那个类,这样的话就只能用BPL,且主程序一定要
Build with runtime packages才行。
 
我是这样实现的,为我要引出的类定义一个抽象类,然后在DLL中引出类
不过,这样做的缺陷是不能够用is,as了。

function ClassFactory: TDeviceClass
stdcall;
begin
Result := TCharDisplay;
end;
exports
ClassFactory;
 
哦,,你的想法是这样的所?

研究研究!!!
 
tseug:
这样个做法对于我目前的情况来说比较麻烦,因为我的每个BPL里有很多个类(FORM),加
上开始做时没有考虑用DLL来分模块,所以现在再来这么做基本上是不可能了。而且我们为了
避免单元之间的互相引用,大量采用了RegisterClass,FindClass的方法。现在经我研究发现
把各块分成BPL是最好的办法了,原来用的全局变量也可以照用(放在BPL里后一样可以当全局
变量用,这用DLL是不可能做到的)。

HeyTommy:
其实就是把Delphi的一些BPL分发也不是不可以,但现在麻烦的是,因为我自己的BPL也引用
了其他第三方控件的BPL,后来我才发现在Package里的Require部分引用的所有BPL都在运行时
需要装载,这就意味着我要发布一大堆BPL了,这对后期维护来说肯定是很不利的。特别是要进
行版本升级的时候,搞不好还不如一个EXE来得比较方便。 :(
 
我在项目中开始也考虑用BPL,后来考虑到每一个设备的驱动程序(我自定义用于驱动硬件
的那部分代码)不一定要用Delphi实现,所以采用了引出类的方法。不过你目前的情况好
像还是用一个EXE比较好,因为分发Delphi自身的BPL经常会有一些莫名其妙的问题。
 
这个问题我很早在CSDN提过,但最后也是不了了之,我的想法是:Build with runtime packages
可以随便我控制,就是Build With我自己的bpl文件,因为Borland和第三方控件那些bpl是固定的,
我们可以另外打包一次性装到客户的系统目录下,然后我们无论升级也好,维护也好,只需要改动
我们自己的bpl文件即可,多方便!甚至我还想Delphi究竟是采用什么机制来联接运行期包的呢?
对于Build with runtime package,Delphi默认是联接什么包呢?我可以自定义而不选中
Build with runtime package选项吗?问题是,选中与不选中就两种状态,熊掌与鱼不可兼得呀!

你把该选项选中,然后单纯加入自己的bpl文件,分发的时候把那些bpl文件也一起拷贝放到同一个
目录下,程序就能正常运行了。至于Delphi自带的bpl和第三方控件,你可以另外打包,放到用户
的系统目录下,是个比较简便的做法。
 
如果你没有自己做控件,或者你做了控件但是没有用到属性编辑器等ToolAPI里的东东,
那也许可能不需要外加RTL60.bpl,但是我想你的BPL中一定用到TOOLAPI的东东了.
 
to xianjun:
两年多前,我在newsgroups.borland.com问过这个问题。
结果TeamB的人回答是,设计意图就是如此。
也就是说,无法抛弃掉其他所需要的BPL。
没办法,最好的方法就是做成单个EXE,要么就从头就设计成DLL。
 
另:
“ BPL跟DLL应该是差不多的东西,但也不是完全一样,Delphi对它作了特殊处理:如DLL里的
全局变量对每一个用LoadLibrary进来的程序而言都是独立的,但BPL就不是了。具体描述你
可以看一下李维写的:《如何使用Delphi開發大型主從架構系統-Package的秘密和威力》
http://www2.borland.com.tw/tw/reference9.html”
这里面李维对DLL的描述是错误的。
32bit 下,DLL在进程间的内存空间是独立的,所以全局变量是不相等的
而在进程内,即使多个模块LOAD同一个DLL,其内存空间是一致的,所以全局变量
在任何调用者看来也是相同的,这和BPL是完全一致的。
李维的例子是错误的,但是他关于BPL的APPLICATION全局变量的图没有问题
将BPL协作图修改成DLL协作图同样也是正确的
当然,DELPHI的编译器可以直接认识BPL里的全局变量APPLICATION
如果要用DLL来使用这样的全局变量,就必须提供输出函数
例如GetGlobalXXXX
函数内容就是 result:= someGlobalVar;

李维的错误就是恰好偷换了“进程”和“模块”的概念
想想,倘若BPL在进程间也可以保障全局变量APPLICATION一致,
那不是乱套了吗。所有用BUILD WITH RUNTIME PACKAGE的程序的APPLICATION岂不都一样了?

 
多谢各位的参与
更就多谢wenyue给了一个肯定的答复,我的试验结果也是,没有办法摆脱那些基础的BPL
其实想想应该也是,如果可以把那些BPL都静态链接进入EXE或BPL内的话,Borland也就不
用那么辛苦的在deploy.txt把一个个版本里可以发布的BPL列出来了。 而且用BPL的缺点也
是显而易见的:1、模块之间耦合太紧,做到后面可能整个系统还是比较乱。2、如果使用了
第三方的控件包的话,还得发布第三方的BPL,因为无法也其他BPL里提供的代码链接到我自
己的BPL中(至少我不知道有这样的方法)。
至于全局变量的问题,可能我说的跟你说的还是有些不一样。你说的全局变量是指一个BPL
或DLL内部的全局变量,而我说的呢却是EXE文件与所有装载入的BPL的全局变量:比如你有
一个单元叫GLobe.pas,里有一个全局变量A,你的EXE中的某个单元引用了Globe,并对全局
变量A作更改,然后你用LoadPackage把一个BPL装载进入,而且此BPL中的某一单元也引用
同一个Globe,此时如果它访问全局变量A的话,它能取出你在主程序EXE中所作修改后的值。
这对于DLL来说是绝对不可能的。即使是BPL,如果你的EXE没有Build with runtime package
也是不可能做到这一点。所以你说的全局变量只是DLL自己的全局变量,你提供一些外部访
问它的方法,对EXE来说它不是自己的全局变量,只是引用DLL的某个方法取得的某一值。
我已经放弃了分模块分成BPL的想法了,因为那样会搞得更复杂,还是花点时间分成DLL吧,
虽然在深度论坛上有位朋友说他有系统就是用BPL划分模块。
 
后面为李维文章中间的原文,其中“因 為 在 Win 3.x 中 所 有 的 模 組 都 使 是 共 用 一 份 DLL 中 的 全 域 變 數”
尤其值得注意,李维在该文中将DLL不能直接共享全局变量的原因归咎到了16BIT和32BIT
的差异。这就是最大的错误。
正如xianjun所说的,在非使用BPL模式下,如果引用了某个单元,那么该单元的DATA以及CODE
均会静态联结到该项目。这样,无论是全局变量,还是代码,都与同样引入了该单元的DLL的是相对独立的,
这才是导致全局变量不全局的原因所在:无论是在win 3.x下,还是在9x/NT下,均如此。
因此,李维在这篇文章内的描述是错误的。
我们仔细从其文字和其图示中发现,李维似乎试图传递一个这样的观点:
32位进程内DLL的全局变量无法保障其唯一性,16位才可以。
"為 什 麼 在 我 一 開 始 使 用 DLL時 無 法 解 決 多 個 模 組 共 用 一 個 資 料 模 組 DLL的 問 題 呢 ? 這 主 要 是 因 為 在 Win 95/NT中 當 每 一 個 模 組 載 入 DLL時 , 對 於 每 一 個 DLL之 中 的 全 域 變 數 而 言 , 每 一 個 模 組 都 會 有 一 份 獨 立 的 變 數 。 這 是 什 麼 意 思 呢 ? 我 們 可 以 使 用 圖 二 來 說 明 。
圖 二 Win 95/NT 中 全 域 變 數 和 模 組 的 關 係
當 圖 二 中 的 模 組 一 和 模 組 二 分 別 的 載 入 它 們 共 用 的DLL 時 , 雖 然 在 這 個 共 用 的 DLL 中 有 一 個 全 域 變 數gAccount 。 但 是 模 組 一 和 模 型 二 會 分 別 的 擁 有 一 個gAccount 變 數 。 這 也 就 是 說 模 組 一 對 於gAccount 變 數 數 值 所 做 的 修 改 並 不 會 影 響 模 組 二 中 的gAccount 變 數 數 值 。 在 Wn 95/NT 中 的DLL 行 為 是 和 Win 3.x 不 同 的 , 因 為 在 Win 3.x 中 所 有 的 模 組 都 使 是 共 用 一 份 DLL 中 的 全 域 變 數 。
由 於 Win 95/NT 中 DLL 全 域 變 數 的 這 種 特 性 , 所 以 當你 想 把 資 料 模 組 撰 寫 在DLL 之 中 讓 多 個 模 組 共 同使 用 時 , 問 題 就 來 了 。 因 為 在 這 種 情 形 下 , 每 一 個 模 組 都 會 有 一 份 它 自 己 的 資 料 模 組 。 所 以 當 每一 個 應 用 程 式 模 組 載 入 資 料 模 組 的 DLL 時 , 它 仍 然 會 連 結 資 料 庫 一 次 , 所 以 你 並 無 法 減 少 連 結資 料 庫 的 次 數 。
"
 
顶部