delphi - Interface DLL form app crashing -


i have problem host application, loads dll form , interfaceing function , properties.

the purpose load dll, show name module name, set connection adotable component , show form data. working fine. after close host app host app crashed , windows hostapp.exe stopped working.

i not know whether freeing library or setting nil interface.

do have solution? thanks.

interface code

unit u_baseplugin_intf;  interface  uses data.win.adodb, data.db;  type   ibasemoduleinterface = interface   ['{060a9c46-b3cf-4ba4-b025-2dc1d9f45076}']   function getmodulename: ansistring;stdcall;   procedure setconn(sconn:tadoconnection);stdcall;   procedure showf;stdcall;   procedure freef;stdcall;    property modulename: ansistring read getmodulename;   property connection : tadoconnection write setconn;   end;  implementation  end. 

dll code

library profileslist;  uses   system.sysutils,   system.classes,   u_baseplugin_intf,   u_profileslist in 'u_profileslist.pas' {form_dll};  {$r *.res}  function loadmodule:ibasemoduleinterface;stdcall; begin   result:=tform_dll.create(nil); end;  exports   loadmodule;  begin end. 

dll form code

unit u_profileslist;  interface  uses   winapi.windows, winapi.messages, system.sysutils, system.variants, system.classes, vcl.graphics,   vcl.controls, vcl.forms, vcl.dialogs, vcl.grids, vcl.dbgrids,  vcl.stdctrls,   u_baseplugin_intf, data.db,data.win.adodb;  type   tform_dll = class(tform, ibasemoduleinterface)     dbgrid1: tdbgrid;     adotable1: tadotable;     datasource1: tdatasource;     procedure formshow(sender: tobject);     procedure formclose(sender: tobject; var action: tcloseaction);   private     { private declarations }     {interface methods implementation}     function getmodulename: ansistring;stdcall;     procedure setconn(sconn:tadoconnection);stdcall;   public     { public declarations }     {interface methods implementation}     procedure showf;stdcall;     procedure freef;stdcall;   end;  var   form_dll: tform_dll;  implementation  {$r *.dfm}  {interface methods implementation} function tform_dll.getmodulename; begin   result := 'profiles list'; end;  procedure tform_dll.setconn(sconn: tadoconnection); begin   adotable1.connection:=sconn; end;  procedure tform_dll.showf; begin   showmodal; end;  procedure tform_dll.freef; begin   freeandnil(form_dll); end;  {form_dll methods implementation} procedure tform_dll.formclose(sender: tobject; var action: tcloseaction); begin   adotable1.active:=false; end;  procedure tform_dll.formshow(sender: tobject); begin   adotable1.active:=true; end;  end. 

host app code

program hostapp;  uses   vcl.forms,   u_hostapp in 'u_hostapp.pas' {form1},   u_baseplugin_intf in 'u_baseplugin_intf.pas';  {$r *.res}  begin   application.initialize;   application.mainformontaskbar := true;   application.createform(tform1, form1);   application.run; end. 

host app form code

unit u_hostapp;  interface  uses   winapi.windows, winapi.messages, system.sysutils, system.variants, system.classes, vcl.graphics,   vcl.controls, vcl.forms, vcl.dialogs, vcl.stdctrls, vcl.extctrls,    u_baseplugin_intf,   data.win.adodb, data.db;  type   tform1 = class(tform)     adoconnection1: tadoconnection;     button1: tbutton;     label1: tlabel;     procedure button1click(sender: tobject);     procedure formclose(sender: tobject; var action: tcloseaction);     procedure formcreate(sender: tobject);   private     { private declarations }   public     { public declarations }   end;  type   tmoduleinterface = function:ibasemoduleinterface; stdcall;  var   form1: tform1;  implementation  {$r *.dfm} var   amoduleintf : ibasemoduleinterface;   dllhandle : cardinal;  procedure loadmodule( alibname : pwidechar ); var    lmodule : tmoduleinterface;  begin    dllhandle := loadlibrary(alibname) ;    if dllhandle <> 0    begin      @lmodule := getprocaddress(dllhandle, 'loadmodule') ;      if assigned (lmodule)        amoduleintf := lmodule //call function      else       begin         showmessage('getmoduleintf not found.') ;         freelibrary(dllhandle) ;       end;    end    else    begin      showmessage(alibname+' not found.') ;    end;  end;  procedure tform1.button1click(sender: tobject); begin   amoduleintf.connection:=adoconnection1;   amoduleintf.showf; end;  procedure tform1.formclose(sender: tobject; var action: tcloseaction); begin   amoduleintf.connection:=nil;   amoduleintf.freef;   amoduleintf:=nil;   freelibrary(dllhandle); end;  procedure tform1.formcreate(sender: tobject); begin   loadmodule('profileslist.dll');   label1.caption:=amoduleintf.modulename; end;  end. 

you never assign form_dll. means when call freef, perform freeandnil(form_dll). since form_dll nil, nothing, , form still exists.

fix changing loadmodule:

function loadmodule:ibasemoduleinterface;stdcall; begin   assert(not assigned(form_dll));   form_dll:=tform_dll.create(nil);   result:=form_dll; end; 

although, i'd change design removing form_dll altogether. host app maintains reference form, on call free can made. in other words, remove form_dll , implement freef this:

procedure tform_dll.freef; begin   free; // or destroy end; 

or better, use reference counted interfaces on implementing object , let amoduleintf:=nil take form down.


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -