模块化程序设计,用DLL还是COM/COM+?(总额可达1000分,先发300分)(300分)

  • 主题发起人 主题发起人 WiseAnt
  • 开始时间 开始时间
我作的这类程序,也很不够稳定
基本上也是因为dllform释放的问题
我在2000上写的Dllforom,也明显不够稳定
在同时加载多个dllform后,关闭其中一个,
就会给我退出主程序
但在NT4下,是没有什么问题的。
 
我现在有个项目,软件要通过拨号网络进行维护。程序更新后能自动进行下载。
可能用Dll比较方便。
关键是数据库连接怎么处理,是每个Dll中单独建数据连接模块?
还是建一个数据连接? 我用的是ADO作的数据库连接。
WiseAnt: 你的项目怎么样了啊?是怎么处理的?可以给段代码吗?将不胜感谢!
 
if mItem.IntakeFunc<>'' then
begin
s := pModule^.IntakeFuncs;
j := s.IndexOf(mItem.IntakeFunc);
if j<0 then
Exit;
pModule^.PSetOldApplication;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~``[red]这个语句有问题 pModule^.PSetOldApplication是一个空指针
你看一下前面加载模块时是否有指针没有处理好,我看得头晕![/red][:(]
pModule^.IntakeFuncs.Delete(j);
pModule^.ModuleForms[j] := nil;
pModule^.PLoadModuleForms[j] := nil;
for n:=j to pModule^.LoadCount-2do
begin
pModule^.ModuleForms[n] := pModule^.ModuleForms[n+1];
pModule^.PLoadModuleForms[n] := pModule^.PLoadModuleForms[n+1];
end;

Dec(pModule^.LoadCount);

end else
begin
....
 
to softdog:
  pModule^.PSetOldApplication[red]并非一个空指针[/red],你可以在uDllCommon.pas
单元的SetOldApplication函数实现部分加上一句:
Application.MessageBox('Will set the Application=OldApp', '', 0);
试试,可以正确显示以上消息的,如果只是在IDE环境中查看pModule^.PSetOldApplication
的值,当然是看不到,但你应该看得到[red]pModule^[/red]变量的值,其中的PSetOldApplication
值并非空,如果是空的话,在TLoadModule.Delete函数内部就应该出错了,可是为何调用完了
Delete方法后才出错?
to 逍遥泿子:
  你可以下载看一下我上面给出的例子,其中对接口的定义是这样的:
{定义动态载入的DLL模块接口函数}
TLoadModuleForm = function (App:TApplication;PFormFreeCallBack:Pointer;
vConnect: TAdoConnection=nil):TForm;stdcall;
在DLL模块内部也是提供一个同以上声明一样的一个函数并导出让主程序调用,DLL内部
所有建立的窗口如果要用到ADO连接的话,就传上面的连接传给子窗口。
你先看看吧,很简单的,相信你能搞定![:)]
  
 
>pModule^.PSetOldApplication并非一个空指针,你可以在uDllCommon.pas
>单元的SetOldApplication函数实现部分加上一句:
> Application.MessageBox('Will set the Application=OldApp', '', 0);
>试试,可以正确显示以上消息的,如果只是在IDE环境中查看pModule^.PSetOldApplication
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这不代表对pModule^.PSetOldApplication指针的赋值是正确的,
因为你的程序里好像“转了几道弯”,我不知道是不是在这期间发生了指向错误。
>的值,当然是看不到,但你应该看得到pModule^变量的值,其中的PSetOldApplication
~~~~~~~~~~~~~~~~~~ 当然看不到?你试过吗?我调试我的程序时从来都是可以看到的。
>值并非空,如果是空的话,在TLoadModule.Delete函数内部就应该出错了,可是为何调用完了
>Delete方法后才出错?
可能因为是回调函数,和其他函数执行机制不一样。
 
sorry,刚才搞错了一点:pModule^.PSetOldApplication因为是TSetOldApplication类型所以在IDE中是看不到。[:)]
我再看看。
 
请教一个小问题:
假设在
procedure TFmTestChild.FormDestroy(Sender: TObject);
begin
FormFreeCallBack(Handle);
//加入t;
end;
是不是程序在调用完主程序的FormFreeCallBack后再运行t;
如果是的话,那么程序设计就有误:
在TLoadModules.Delete就不能调用
 FreeLibrary (pModule^.ModuleHandle);
----------------------
屏蔽这两句就程序没问题:
//pModule^.PSetOldApplication;
//FreeLibrary (pModule^.ModuleHandle);
 
感谢ZZHI,我只去掉了下面一句好象就不出错了:
//FreeLibrary (pModule^.ModuleHandle);
可是,我该在何时FreeLibrary呢?
 
只能加个自定义消息,用PostMessage试试吧,或者用线程。。。。
 
这句有问题:pModule^.PSetOldApplication;
你可能还要考虑一下!
//Delphi5+win2000
 
>>这句有问题:pModule^.PSetOldApplication;
我的也是Delphi5+win2000呀,可我的怎么也不出问题,能告诉我具体出什么问题吗?
>>只能加个自定义消息,用PostMessage试试吧
在自定义消息中FreeLibrary就不会出错吗?可能子窗口发出这个消息后,在处理这个
消息时子窗口的处理并没有结束呢?
 
可能是系统的问题,但好像在98下也是出这个问题,要晚上回家看看:
Access violation at address 0157b87b in module 'Module02.DLL'.Read of Address
0000023C.
//---------------------
是在MainFrm中定义一个消息。如UnLoadLib,用
PostMessage(Unloadlib....)代替FreeLibrary (pModule^.ModuleHandle);

 
先感谢ZZHI,我在深圳,我的QQ是:12193017,如果以后有什么问题我可以帮得上忙的(我
能帮上忙的可不多哟),我一定顶力相助,3x!
 
稍作修改就可以了..............
unit uDllCommon;
....
implementation
uses TestChildFrm;[:)]
....
finalization
Application := OldApp;
FormFreeCallBack(123);[:)]
end.
完事了!
 
to rrr:
  谢谢你的回答,不知你的123是从哪儿来的。稍做处理应该可以做到,这样在程序
运行时应该是不会有问题的,但我的uDllCommon单元是一个供所有动态DLL模块使用的
单元,不应该做成这个样子。而且最重要的是[red]finalization是在FreeLibrary时执行[/red],
而我的[red]目的就是FreeLibrary[/red]!
to ZZHI:
我试了一下用自定义消息,果然可以,但必须是在TFmTestChild.FormDestroy过程的
最后一行,否则还是会出同样的错误,不知还有没有更完善的办法?3x[8D]
 
to rrr:
你这和 //FmMain.LoadModules.Delete 的作用差不多吧!
好像:unit uDllCommon中的finalization段
要由FreeLibrary 或主程序结束才会执行吧!
 
FormFreeCallBack必须在最后,因为你的主程序FormFreeCallBack中含有FreeLibrary,
如果FormFreeCallBack后还有其他语句的话,结果就不要说了。
//--------
可以不放在最后,那就要求主程序FormFreeCallBack中不含FreeLibrary就可以!
 
dll能够提供函数,这没问题。但是dll中的数据你怎样访问呢?无法直接访问,只有通过函数
——其实这就是com。
 
TFmTestChild可以不改!
在FmMain中定义一个消息UnLoabLib,调用FmMain.LoadModules.Delete
FormFreeCallBack中FmMain.LoadModules.Delete用
PostMessage(self.handle,UnLoabLib....)代替好一些!
 
to ZZHI:
  还没试,不过我感觉应该是好一些了。那是否回调函数还是应该放在子窗口销毁事件
处理过程的最后一行呢?
  不过我想这样处理至少比PostMessage方式更具弹性了!
  我先回家试试,明天见!3x!
 
后退
顶部