Solved

need help with "MethodAddress"

Posted on 2000-03-08
10
276 Views
Last Modified: 2010-04-04
hi all:
i wanna get a function's address by MethodAddress, and then call it.
But, in the function, if i access a VCL(eg. form,memo), i always get a "Access violation" error. if dont access VCL, it works fine.

how to resolve it? thanks!
0
Comment
Question by:cAkk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 1

Expert Comment

by:yk030299
ID: 2599401
pls show here your codes for us to understand your situation.
"Access voilation" means you are accessing address was not allocated to your program.
it often happened when you code that in a function:

in method
 procedure TForm1.metho1();
 begin
   //Form1.property1:=something;
   //Form1.method2();
   //something like that!!!
 end;
 ...
  var F:TForm1;
  F:=TForm1.Create(application);
  F.method1;

it means Form1 is not created but want to call it.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599411
Yes, please post a code snippet where you get the error.

Cheers,

Raymond.
0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 150 total points
ID: 2599434
OK...

Methodaddress returns a pointer to the code for that published method in a class. But to call it you must be in the context of an instance of the class.

You can use a TMethod to hold the pointer to the instance data and the pointer to a methodaddress result.

Here is an example:

unit Unit18;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   published
     procedure a;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.a;
begin
  ShowMessage('!');
end;

procedure TForm1.Button1Click(Sender: TObject);
type
  t = procedure of object;
var
  x : tmethod;
  y : t;
begin
  x.data := @self;
  x.code := self.methodaddress('a');
  y := t(x);
  y;
end;

end.

Cheers,

Raymond.

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599438
Where I Said: "But to call it you must be in the context of an instance of the class." I really meant you need to have the context of an instance, you don't need to be in the instance itself to call it.

Cheers,

Raymond.
0
 

Author Comment

by:cAkk
ID: 2599839
i do as this:

type
  tform1=class(tform)
   ....
  published
   procedure abc;
end;

....

procedure tform1.abc;
begin
  //error occur at this sentence
  memo1.lines.add('abc');
end;

procedure tform1.buttonclick(...);
var func:procedure;
begin
  func:=MethodAddress('abc');
  func;
end;
0
 

Author Comment

by:cAkk
ID: 2599846
rwilson :

in your sample code, drag a TMemo to your form, and replace "showmessage" with "memo1.lines.add(...);"

the error will occur.

i means: if you access a VCL in the function, it dont work.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2602199
Whoops: I didn't need to take the address of self, just cast it to a pointer. The following works:

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   published
     procedure a;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.a;
begin
memo1.lines.add('...');
end;

procedure TForm1.Button1Click(Sender: TObject);
type
  t = procedure of object;
var
  x : tmethod;
  y : t;
begin
  x.data := pointer(self);
  x.code := self.methodaddress('a');
  y := t(x);
  y;
end;

Cheers,

Raymond.
0
 

Author Comment

by:cAkk
ID: 2602812
rwilson: your code works. but, if i want add parameters to function "a", how to do that?

eg: procedure a(s:string)
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2602864
You need to know what the parms are in advance, and declare the appropriate proc type and function:

   published
     procedure a(Arg : Integer);

type
  t = procedure(Arg : Integer) of object;


Cheers,

Raymond.
0
 

Author Comment

by:cAkk
ID: 2603661
i see. thanks!
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
Suggested Courses
Course of the Month8 days, 15 hours left to enroll

615 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question