这是我的一个框架程序,框架分为三部分,1.主程序(exe) 2.数据模块(dll) 3.子窗体(dll)数据模块dataunit.dll中输出一个函数,生成一个DataModule对象并返回它.
字窗体TestDLLForm.dll中输出一个函数,生成一个Form对象并返回它.
主程序引入这两个动态库函数,在OnCreate时调用它们,生成一个DataModule和Form, OnDestroy时释放这两个对象.
这个程序在不使用Run Time Package时,没有问题.但是,如果使用了Run Time Package,主程序在释放DataModule时就会报错,这是什么原因?另外,按照帮助文档:在动态库输出的函数中,如果传递的参数用到了字符串和动态数组(或是内嵌了字符串和动态数组),就应该uses sharemem. 我这里传递的参数是TObject的子类,它的很多属性都是字符串,按理需要uses sharemem,但是我没有用,也没出错,这是什么原因?动态库中用到了TXmlDocument控件时,就一定要调用 CoInitialize(nil)和 CoUninitialize.调用它们的主程序是否也需要调这两个函数?
以下是我的源程序一.主程序是一个简单的窗体,如下
//main.pasunit Main;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Main, xmldom, XMLIntf, msxmldom, XMLDoc;type
  TMainFrmImp = class(TForm)
    XMLDocument1: TXMLDocument;
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure LoadShareData;//从动态库中加载数据模块
    procedure LoadChildForm;//从动态库中加载子窗体
  public
    { Public declarations }
    DataModule:TDataModule;
    ChildForm:TForm;
  end;var
  MainFrmImp: TMainFrmImp;implementation
function CreateShareData(AHandle:THandle;AOwner:TMainFrmImp):TDataModule;
  stdcall;external '..\sharedata\dataunit.dll';
function CreateForm(AHandle:THandle;MainFrm:TMainFrmImp):TForm;
  stdcall;external '..\DllForm\TestDLLForm.dll';
{$R *.dfm}procedure TMainFrmImp.FormDestroy(Sender: TObject);
begin
  if Assigned(DataModule) then
    DataModule.Free;
  if Assigned(ChildForm) then
    ChildForm.Free;
end;procedure TMainFrmImp.FormCreate(Sender: TObject);
begin
  LoadShareData;
  LoadChildForm;
end;procedure TMainFrmImp.LoadChildForm;
begin
  ChildForm:=CreateForm(Application.Handle,Self);
  ChildForm.Show;
end;procedure TMainFrmImp.LoadShareData;
begin
  DataModule:=CreateShareData(Application.Handle,Self);
end;end.这个程序在启动时从动态库中加载子窗体和数据模块,关闭时释放它们.二.数据模块 把一个DataModule放在一个动态库中,exports一个函数来生成它//sharedata.pas
unit sharedata;interfaceuses
  ActiveX,SysUtils, Classes,Main,Forms, xmldom, XMLIntf, msxmldom, XMLDoc;type
  TShareDataModule = class(TDataModule)
    XMLDocument1: TXMLDocument;
  private
    { Private declarations }
  public
    { Public declarations }
    MainForm:TMainFrmImp;
  end;var
  ShareDataModule: TShareDataModule;
function CreateShareData(AHandle:THandle;AOwner:TMainFrmImp):TDataModule;stdcall;
implementation
{$R *.dfm}
function CreateShareData(AHandle:THandle;AOwner:TMainFrmImp):TDataModule;
begin
  Application.Handle:=AHandle;
  ShareDataModule:=TShareDataModule.Create(Application);  ShareDataModule.MainForm:=AOwner;
  result:= ShareDataModule;
end;initialization
  CoInitialize(nil);
finalization
  CoUninitialize;
end.三.子窗体 把一个Form放在一个动态库中,exports一个函数来生成它unit FormUnit;interfaceuses
  ActiveX,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Main, xmldom, XMLIntf, msxmldom, XMLDoc;type
  TFrmTest = class(TForm)
    XMLDocument1: TXMLDocument;
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  FrmTest: TFrmTest;
function CreateForm(AHandle:THandle;MainFrm:TMainFrmImp):TForm;stdcall;
implementation
function CreateForm(AHandle:THandle;MainFrm:TMainFrmImp):TForm;
begin
  Application.Handle:=AHandle;
  FrmTest:=TFrmTest.Create(Application);
  result:=FrmTest;
end;
{$R *.dfm}
initialization
  CoInitialize(nil);
finalization
  CoUninitialize;
end.

解决方案 »

  1.   

    >>动态库中用到了TXmlDocument控件时,就一定要调用 CoInitialize(nil)和 
    >>oUninitialize.调用它们的
    >>主程序是否也需要调这两个函数?
    主程序不用!! 因為在某個, 可能是 system 中的初始化中已經調用了!!
      

  2.   

    为什么不能用Run Time Package呀,这是最严重的问题!
      

  3.   

    >>为什么不能用Run Time Package呀
    我以前也遇到過類似你的問題, 後來是一個同事解決的, 沒告訴我!! 我沒法給給出答案, 但我證明絕對有這個可能!!
      

  4.   

    我认为不时runtime package的错,还是应该查一下你程序哪里少释放内存了。。
      

  5.   

    我发现,问题出在
    FrmTest:=TFrmTest.Create(Application);
    把Application改成主窗体,或nil,就好了.