我将MDI子窗体封装在DLL中,然后用主程序来调用动态,显示以及子窗口中的功能都没问题,但是在关闭主窗口的时候总是会报内存地址错误!

解决方案 »

  1.   

    有可能是DLL中变量的问题,把变量都放到private下,而且有些变量要在退出前进行释放。最好把DLL代码贴出来看看
      

  2.   

    有可能是DLL中变量的问题,把变量都放到private下,而且有些变量要在退出前进行释放。最好把DLL代码贴出来看看
      

  3.   

    没的人回话呢?源码如下
    ibrary pDll;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      ShareMem,
      SysUtils,
      Classes,
      Forms,
      Dialogs,
      BascUnit in 'BascUnit.pas' {BascForm},
      Base in 'Base.pas' {BaseForm},
      FrmPub in 'FrmPub.pas',
      pub in 'pub.pas' {Form1},
      UIImage in 'UIImage.pas',
      UIStyle in 'UIStyle.pas' {UIStyleForm},
      Unit_alterDepartNode in 'Unit_alterDepartNode.pas' {Manager_alterDepartNode},
      Unit_alterEmploy in 'Unit_alterEmploy.pas' {Manager_alteremploy},
      Unit_areasAlter in 'Unit_areasAlter.pas' {Manager_areasAlter},
      Unit_depotAlter in 'Unit_depotAlter.pas' {Manager_depotAlter},
      Unit_frmSelect in 'Unit_frmSelect.pas' {FrmSelectn},
      Unit_getcontrolmessage in 'Unit_getcontrolmessage.pas' {dataGetctrol: TDataModule},
      Unit_PubModule in 'Unit_PubModule.pas' {PubModule: TDataModule},
      Unit_TreeNodeModule in 'Unit_TreeNodeModule.pas',
      UnitFilterForm in 'UnitFilterForm.pas' {FilterForm},
      Unit_ImportName in 'Unit_ImportName.pas' {frmImportName},
      Unit2 in 'Unit2.pas' {Form2};{$R *.res}
    Var
      oldApp : TApplication ;
    Procedure InitChildDll(pApp:TApplication);stdcall;   //保留应用程序对象
    Begin
      oldApp:= Application ;
       Application := pApp ;
    End;Procedure FreeAppDll(); //还原应用程序对象
    Begin
       Application:= OldApp ;End;Procedure OpenWindows(MenuValue:String;pSysinfo : TSysInfo);stdcall;
    Var
    //FrmBaseList: TFrmBaseList;
    BascForm: TBascForm;
    Ptr:PLongInt;
    SysInfo:TSysInfo ;
    strErr:WideString ;
    //sPubModule:TPubModule ;
    Form2:TForm2 ;
    begin
        Form2:= TForm2.Create(application.MainForm);
        Form2.Show ;
      // Ptr:=@(Application.MainForm);
      // Ptr^:=LongInt(MainForm);  { IF not Assigned(PubModule) Then
       Begin
         Application.CreateForm(TPubModule, PubModule);
         PubModule.Name:='dLlPubModule';
         //sPubModule := TPubModule.Create(application);
         SysInfo := pSysinfo  ;
         PubModule.ServerPort := PsYSInfo.sys_ServerPort ;
         PubModule.ServerIp := PsysInfo.sys_ServerIp ;
         //PubModule.sPass:= pSysInfo.sys_Pass ;
         PubModule.sUserCode:= pSysInfo.sys_UserCode ;
         PubModule.sUserName:= pSysInfo.sys_UserName ;
         PubModule.sLogDatetime:= pSysInfo.sys_LogTime;
         PubModule.dbname:= pSysInfo.sys_LogDbName ;
         PubModule.SckSvrConnection(strErr);
         PubModule.LoginDbServer(SysInfo.sys_LogDbName ,strErr);   End;
       IF not Assigned(dataGetctrol) Then
       Begin
        // dataGetctrol := TdataGetctrol.Create(application);
          Application.CreateForm(TdataGetctrol, dataGetctrol);
          dataGetctrol.Name:='dLLdataGetctrol';
       End;  } //  ModuleName:= MenuValue ;  // BascForm:=TBascForm.Create(application);  //  BascForm.Caption:=MenuValue;
      // BascForm.Show;
        
    End;
    exports
    InitChildDll,
    FreeAppDll,
    OpenWindows ;beginend.
      

  4.   

    给你一个模板吧,照着改一下你的程序
    library MyDLLForm;uses
      SysUtils,
      Classes,
      Forms,
      Windows,
      uChild in 'uChild.pas' {frmDLLForm};{$R *.res}var
      DLLApp: TApplication;
      DLLScr: TScreen;
    function CreateDLLForm(App: TApplication; Scr: TScreen):TForm;
    begin
      Application := App;
      Screen := Scr;
      Result:=TfrmDLLForm.Create(nil);
    end;procedure ExitDLL(Reason: Integer); 
    begin 
      if Reason = DLL_PROCESS_DETACH then 
      begin 
        Application := DLLApp; 
        Screen := DLLScr; 
      end; 
    end; 
    exports 
      CreateDLLForm; begin 
      DLLApp := Application; 
      DLLScr := Screen; 
      DLLProc := @ExitDLL;
    end.
      

  5.   

    问题是一样的,还是不行,如果把子窗体中的DevExpress控件删除掉的话就可以
      

  6.   

    initialization
      coinitialize(nil);
      finalization
      counInitialize;
    end.
    在任何一个窗体里面加以上这段代码。只要加一次。
      

  7.   

    试试这样,将下面这句
    Form2:= TForm2.Create(application.MainForm); 
    改成:
    Form2:= TForm2.Create(nil); 但用完后自己释放,做个记录。
      

  8.   

    去掉
    ShareMem, 
    单元,试试看
      

  9.   

    给你参考一下吧 这是我上个世纪用的代码
      TWinParam = record
        Application: TApplication;
        FormName: string; //功能名称
        Connection: TAdoConnection;
        Operator: TUserInfo;
      end;
      PWinParam = ^TWinparam;function ShowIt(param: TWinParam): Thandle; stdcall; export;
    var
      aForm: TFrmBase;
      aClass: TPersistentClass;
      theName: string;
    begin
      Application := param.Application;
      theName := uppercase(trim(param.FormName));
      if LeftStr(theName, 1) <> 'T' then
        theName := 'T' + theName;
      try
        aClass := FindClass(theName);
        aForm := TfrmBase(aClass.create).Create(Application.MainForm);
    //    aForm.Parent := Application.MainForm;    aForm.showFrm(param.Connection, param.Operator);
        result := aForm.Handle;
      except
        MessageDlg('本功能尚在开发中或者系统无此功能。', mtInformation, [mbOk], 0);
        result := 0;
      end;
    end;