delphi - Procedure in a component that uses another procedure in a DLL -


i having problem trying create procedure component uses procedure contained in dll (texecute) needs declaration in current code. procedure has pointer parameter know evaluation. following code works fine need procedure eval inside component use private variables component. working code following, note eval procedure global in case.

texecute = procedure(eval: pointer, var variablearray: double);cdecl tmycomponent = class(tcomponent) public     fhandle: thandle;     fexecute: texecute;     procedure calculate;  var     n: integer;     x: array of double;  procedure eval(var x: double);  implementation procedure eval(var x:double); var     mx: array[0..200] of double absolute x; begin     mx[0]:= 2*mx[0]; end;  tmycomponent.calculate; begin     fhandle:= loadlibrary(.....);     fexecute:= getprocaddress(fhandle, 'main');      n:=2;     setlength(x,n);      fexecute(@eval,x[0]); end; 

i got problem when put procedure eval inside tmycomponent that:

texecute = procedure(eval: pointer, var variablearray: double);cdecl tmycomponent = class(tcomponent) public     fhandle: thandle;     fexecute: texecute;     procedure calculate;     procedure eval(var x: double);  var     n: integer;     x: array of double;    implementation procedure tmycomponent.eval(var x:double); var     mx: array[0..200] of double absolute x; begin     mx[0]:= 2*mx[0]; end;  tmycomponent.calculate; begin     fhandle:= loadlibrary(.....);     fexecute:= getprocaddress(fhandle, 'main');      n:=2;     setlength(fx,n);      fexecute(@tmycomponent.eval,x[0]); end; 

i project faulted message: access violation @ 0x65900381f: write of address 0x0000005c. process stopped. use setp of run continue.

and don't have no clue problem, tried change , did't solution. if me appreciate.

a global procedure , class method not same thing. class method has hidden self parameter, dll not take account when class method passed dll. why code crashes - call stack not set correctly.

given "working" code, component code needs this:

texecute = procedure(eval: pointer; var variablearray: double); cdecl;  tmycomponent = class(tcomponent) public     fhandle: thandle;     fexecute: texecute;     procedure calculate;     class procedure eval(var x: double); static; end;  var     n: integer;     x: array of double;  implementation  class procedure tmycomponent.eval(var x:double); var     mx: array[0..200] of double absolute x; begin     mx[0]:= 2*mx[0]; end;  procedure tmycomponent.calculate; begin     fhandle:= loadlibrary(.....);     fexecute:= getprocaddress(fhandle, 'main');      n:=2;     setlength(fx,n);      fexecute(@eval,x[0]); end; 

since eval() method accesses global variable, works fine. if needs access members of component, have problem since static directive eliminates self parameter. in case, have 3 options.

  1. if can, change dll function accept additional parameter component can pass self value in, , have dll pass value eval() parameter, eg:

    texecute = procedure(eval: pointer, var variablearray: double; userdata: pointer); cdecl;  tmycomponent = class(tcomponent) public     fhandle: thandle;     fexecute: texecute;     procedure calculate;     class procedure eval(var x: double; userdata: pointer); static; end;  var     n: integer;     x: array of double;  implementation  class procedure tmycomponent.eval(var x: double; userdata: pointer); begin     // use tmycomponent(userdata) needed... end;  procedure tmycomponent.calculate; begin     fhandle:= loadlibrary(.....);     fexecute:= getprocaddress(fhandle, 'main');      n:=2;     setlength(fx,n);      fexecute(@eval, x[0], self); end; 
  2. if #1 not possible, , if there 1 instance of component calling dll function @ time, use global pointer component, eg:

    texecute = procedure(eval: pointer, var variablearray: double); cdecl;  tmycomponent = class(tcomponent) public     fhandle: thandle;     fexecute: texecute;     procedure calculate;     class procedure eval(var x: double); static; end;  var     n: integer;     x: array of double;  implementation  var     mycomp: tmycomponent;  class procedure tmycomponent.eval(var x: double); begin     // use mycomp needed... end;  procedure tmycomponent.calculate; begin     fhandle:= loadlibrary(.....);     fexecute:= getprocaddress(fhandle, 'main');      n:=2;     setlength(fx,n);      mycomp := self;     fexecute(@eval, x[0]); end; 
  3. if #2 not possible because multiple component instances need call dll @ same time, option left use dynamic proxy. allocate block of executable memory , store special stub code in along component self pointer, pass memory block dll if normal procedure. when dll calls "procedure", it's stub code called, can extract component pointer proxy , use needed. approach vcl uses assigning non-static twincontrol.wndproc() method win32 api window procedure callbacks. can't provide code here right now, in vcl's source code @ classes.makeobjectinstance() function example.


Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -