写了一个DLL,里面含有一个窗体,该窗体显示数据库中的一个表的内容,窗体中引用的数据源来自DLL中一个TDataModul中的
TQuery,现在是当主程序调用时,DLL中的窗体能正常显示出数据库表中的内容,但是当主程序退出时,会弹出一个错误,大概意思是:  ******检测到错误'access violation at 0xd0020266:read of address 0xd0020266'我估计是在主调程序退出时,没有手动的释放DLL中TDataDodul中所占用的资源所造成,可是我在DLL工程文件中使用了:
procedure LibraryProc(Reason: Integer);
begin
  if Reason=DLL_PROCESS_DETACH then
  begin
    if Assigned(DM) then
    begin
      if DM.ADOConnection1.Connected then dm.ADOConnection1.Close;
      freeandnil(dm);
      //************
    end;
  end;
end;
Exports
  LoadForm;  //显示数据的窗体
begin
  Application.CreateForm(TDM, DM);
  DLLProc := @LibraryProc;end.还是不行,测试时,在星号的地方插入弹出对话框的窗口,还是没有作用,问题出现在哪呢,高手给我点拔下啊,抓狂在。
PS:
initialization
  CoInitialize(nil);
finalization
  CoUnInitialize;这个调用了,不是COM未初始化的原因

解决方案 »

  1.   

    还有,当我把TADOConnection和TADOQuqry直接放在显示数据的窗体中时,不会有这个问题,
      

  2.   

    调用DLL里封装数据模块问题太多了~~~
    改为BPL封装比较好~~
      

  3.   

    在dll中做一个释放的函数在程序退出时调用此释放函数;dll中创建的,调用程序直接去释放不好(能释放吗?)创建和释放要处在同一"位面",谁创建谁释放
      

  4.   

    写了一个简单的,经测试一切正常library Project2;uses
      SysUtils,
      Classes,
      Windows,
      forms,
      ActiveX,
      Unit1 in 'Unit1.pas',
      Unit2 in 'Unit2.pas' {Form2},           //form2里面是一个dbgrid,显示dm中adoquery1的内容
      Unit3 in 'Unit3.pas' {DM: TDataModule};
    {$R *.res}procedure LibraryProc(Reason: Integer); 
    begin
      if Reason = DLL_PROCESS_ATTACH then
      begin
        CoInitialize(nil);
        if dm=nil then
          dm:=tdm.Create(nil);
        if form2=nil then
          form2:=tform2.Create(nil);
      end;
      if Reason = DLL_PROCESS_DETACH then
      begin
        if Assigned(form2) then
          freeandnil(form2);
        if Assigned(dm) then
          freeandnil(dm);
        CoUninitialize;
      end;end;procedure Test; stdcall;
    begin
      if Assigned(form2) then
        form2.ShowModal;
    end;exports
      Test;
    begin
      DllProc:=@LibraryProc;
      LibraryProc(DLL_PROCESS_ATTACH);end.调用程序
    Ttest=procedure;stdcall;
    procedure TForm1.Button2Click(Sender: TObject);
    var
      FHandle:THandle;
      ftest:Ttest;
    begin
      FHandle := LoadLibrary('project2.dll');
      if FHandle <> 0 then
        begin
          @ftest := GetProcAddress(FHandle, 'Test');
          if @ftest <> nil then
              begin
                ftest;
              end
          else
            showmessage('加载函数失败');
        end
      else
            showmessage('加载dll失败');
      FreeLibrary(FHandle);
    end;最后说一句,静态调用确实会出问题,动态的不会,原因不明,在查中
      

  5.   

    俺一直用dll调用exe中的数据模块,一般不会有太大的问题,直接把adoconnection对象传递过去就可以。