Recent

Author Topic: [SOLVED] How call method by pointer?  (Read 4604 times)

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
[SOLVED] How call method by pointer?
« on: January 20, 2019, 07:03:33 pm »
Look for something like this:
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(ptr:Pointer);
  2.  
  3. Type
  4.   TMyProc = procedure(obj:TObject) of object;
  5.  
  6. var
  7.   myProc : TMyProc;
  8.  
  9. begin
  10.  
  11.   myProc := ??? // here may be ptr
  12.   myProc(nil);
  13.  
  14. end;

Thanks.
« Last Edit: January 20, 2019, 10:34:56 pm by yurkad »

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How call method by pointer?
« Reply #1 on: January 20, 2019, 07:24:18 pm »

 You can simply do this

Proc := A_Procedure_Of_The_Same_Type;
 
 You must provide a procedure that is equal to PROC..

Procedure Test(Obj:Tobject);
Begin
 ….
End;

 Proc := Test;
---
If you are doing Class methods you must change your type.
procedure(Obj:Tobject) of Object;

Proc := Form1.A_Method(Sender:Tobject);

Keep in mind , the calling parameters must be the same as your type.

I did this in DELPHI mode but if you are in fpcObj Mode then you need the use the "@" in front.

Proc := @Test;

Ect.

The only true wisdom is knowing you know nothing

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: How call method by pointer?
« Reply #2 on: January 20, 2019, 07:32:17 pm »
Thank you jamie.

But in your code does not exists ptr.

I do not have direct access to proc test.

Unically can call myProc by pointer ptr.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: How call method by pointer?
« Reply #3 on: January 20, 2019, 07:39:55 pm »
pointer(myproc):=whateverpointer;

Note that this will only work if myproc is a global (unnested) pure procedure.  No methods, no nested procedures.  And you must take care that calling conventions and parameter lists match.

Anything else will lead to crash.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: How call method by pointer?
« Reply #4 on: January 20, 2019, 07:49:27 pm »
This line
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(ptr:Pointer) of object;
is invalid. You can declare a plain procedure or a method (inside object) or a method variable.
Valid is this
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(ptr:Pointer);
or this
Code: Pascal  [Select][+][-]
  1. TMyMethod = procedure CallerByPointer(ptr:Pointer) of object;
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How call method by pointer?
« Reply #5 on: January 20, 2019, 07:54:27 pm »
Your PROC variable is a pointer but it's a TYPED pointer so the compiler knows what it should be
assigned to..

 You can use the @AProcedure to set a generic pointer but when you do this the compiler will no
longer treat it as a Procedure, it will be just a untyped pointer..

 I suppose you can use casting but I really don't know what you are trying to achieve here.

The only true wisdom is knowing you know nothing

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: How call method by pointer?
« Reply #6 on: January 20, 2019, 08:35:13 pm »
Blaazen, thank you. You are right and I corrected it already.

marcov, thanks. Sorry, but I made error.
The myproc is not nested, but it is method of a class.

Line 4 was corrected:
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(ptr:Pointer);
  2.  
  3. Type
  4.   TMyProc = procedure(obj:TObject) of object;
  5.  
  6. var
  7.   myProc : TMyProc;
  8.  
  9. begin
  10.  
  11.   myProc := ??? // here may be ptr
  12.   myProc(nil);
  13.  
  14. end;

So, what can be the solution in this case?

Thanks.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: How call method by pointer?
« Reply #7 on: January 20, 2019, 08:38:37 pm »
I give up, seems there are some stone walls around here.
The only true wisdom is knowing you know nothing

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: How call method by pointer?
« Reply #8 on: January 20, 2019, 09:11:57 pm »
jamie, thanks by good intentions!

Here is some clarification.

I making some class for Lazarus coders. When coder
make code I cannot know your code. But my class, wich coder may to use, must attend all cases possibles.

The procedure myProc is some event metod of TButton. By sample can be
procedure Tfrm.Button1Click(Sender: TObject);

My class must attend each possible event metod of TButton.

I cannot know if coder have opened or not by sample this
procedure Tfrm.Button1MouseEnter(Sender: TObject);   
 
So first my class detect if exists method OnMouseEnter for button1 in  runtime.

And if exists my class must call this method by pointer if is necessary.

The pointer I have by using of PropInfo^.GetProc.

Thus is. 
« Last Edit: January 20, 2019, 09:18:01 pm by yurkad »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: How call method by pointer?
« Reply #9 on: January 20, 2019, 09:51:35 pm »
A pointer is not enough. You must also have self.

Moreover, the calling code is (_very_) complicated, unless you let the compiler generate it.

So the easiest then is to do something like
Code: Pascal  [Select][+][-]
  1. var methodvar : Tsomeprocofobject;
  2.  
  3. TMethod(methodvar).code:= <the address of the function>;
  4. TMethod(methodvar).data:=<self of the function>;
  5. methodvar(...arguments);
  6.  
  7.  

https://www.freepascal.org/docs-html/rtl/system/tmethod.html

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: How call method by pointer?
« Reply #10 on: January 20, 2019, 10:16:02 pm »
marcov, thanks. Yes, it is complicated.

If I understood correctly, now the caller is thus:
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(ptr:Pointer; self:Tobject);
  2.  
  3. Type
  4.   TMyProc = procedure(obj:TObject) of object;
  5.  
  6. var
  7.   myProc : TMyProc;
  8.  
  9. begin
  10.  
  11.   TMethod(myProc).code:= ptr; // ptr obtained as PropInfo^.GetProc
  12.   TMethod(myProc).data:= self; // self is form where is myProc
  13.   myProc(nil);
  14.  
  15. end;
  16.  

In line 13 Error.

Well. I will make it by another way.

Thanks!


yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: How call method by pointer?
« Reply #11 on: January 20, 2019, 10:31:00 pm »
As last attempt I have reviewed way to obtain pointer.

Before I had ptr := PropInfo^.GetProc.

But now made ptr := CurMethod.Code
the code is thus:
Code: Pascal  [Select][+][-]
  1. CurMethod:=GetMethodProp(btn{button1},PropInfo);  
  2. if CurMethod.Code <> nil then
  3.   begin
  4.     ptr :=CurMethod.Code;
  5.     CallerByPointer(CurMethod.Code, mySelf);
  6.   end;

And now all is working.

Later I will publish full code of class.

Thanks again.
« Last Edit: January 20, 2019, 10:33:55 pm by yurkad »

yurkad

  • Full Member
  • ***
  • Posts: 173
  • development
Re: [SOLVED] How call method by pointer?
« Reply #12 on: January 20, 2019, 10:58:13 pm »
Here is a small improvement.

Code for call CallerByPointer:
Code: Pascal  [Select][+][-]
  1. CurMethod:=GetMethodProp(btn{button1},PropInfo);  
  2. if CurMethod.Code <> nil then
  3.   begin
  4. {
  5.     before:
  6.     CallerByPointer(CurMethod.Code, mySelf);
  7. }
  8.   {now:}
  9.     CallerByPointer(CurMethod);
  10.  
  11.   end;

procedure CallerByPointer:
Code: Pascal  [Select][+][-]
  1. procedure CallerByPointer(CurMethod:TMethod);
  2.  
  3. Type
  4.   TMyProc = procedure(obj:TObject) of object;
  5.  
  6. var
  7.   myProc : TMyProc;
  8.  
  9. begin
  10.  
  11.   TMethod(myProc).code := CurMethod.Code;
  12.   TMethod(myProc).data := CurMethod.Data;
  13.  
  14.   myProc(nil); // is working
  15.  
  16. end;

« Last Edit: January 20, 2019, 11:03:02 pm by yurkad »

 

TinyPortal © 2005-2018