Recent

Author Topic: [SOLVED] Troubles with function declaration.  (Read 1869 times)

CM630

  • Hero Member
  • *****
  • Posts: 1296
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
[SOLVED] Troubles with function declaration.
« on: February 12, 2025, 11:41:01 am »
I have a function
function VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;
I use it the following way:
VisaSession.EnableEventHandler(@VisaEventHandler);
This way it works fine.
But I want to register it for the form in which it is used. So I did like always:
Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   { TForm1 }
  4.  
  5.   TForm1 = class(TForm)  
  6. ...
  7. function VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;
  8. ...
  9. implementation
  10. ...
  11. function TForm1.VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;
  12.  

But then the program will not compile.
I get the following error on   VisaSession.EnableEventHandler(@VisaEventHandler); :

Quote
unit1.pas(97,51) Error: Incompatible type for arg no. 1:
        Got "<procedure variable type of function(LongWord;LongWord;LongWord;Pointer):LongInt of object;StdCall>",
expected "<procedure variable type of function(LongWord;LongWord;LongWord;Pointer):LongInt;StdCall>"

Any proposal on how to fix the issue?
Currently, I use Form1.... in the function, maybe I could use a With, but suppose things can be done in the usual way.
« Last Edit: February 19, 2025, 12:39:26 pm by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

cdbc

  • Hero Member
  • *****
  • Posts: 1953
    • http://www.cdbc.dk
Re: Troubles with function declaration.
« Reply #1 on: February 12, 2025, 11:57:25 am »
Hi
Don't put the procedure in the class-declaration, it has to be a 'StandAlone' procedure:
Code: Pascal  [Select][+][-]
  1. type
  2.   TForm1 = class(TForm)
  3.   ...
  4.   end; {TForm1}
  5.  
  6. function VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;
  7.  
  8. implementation
  9. ...
Then I think it'll eat it  :D
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

alpine

  • Hero Member
  • *****
  • Posts: 1372
Re: Troubles with function declaration.
« Reply #2 on: February 12, 2025, 12:06:45 pm »
Here: https://www.freepascal.org/docs-html/ref/refse17.html
TL;DR all methods (procedures declared in a class) unless declared as a class ones, are procedure of object ie. they have a hidden Self argument. If you have a reference to such a type of procedure, you'll need to specify a specific instance of the class in order to substitute for the hidden Self.
You're giving a reference to a method (declared within a class) where a reference to a normal procedure was expected.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1479
    • Lebeau Software
Re: Troubles with function declaration.
« Reply #3 on: February 12, 2025, 05:00:22 pm »
TL;DR all methods (procedures declared in a class) unless declared as a class ones, are procedure of object ie. they have a hidden Self argument.

A class method also has a hidden Self parameter, which points to the class type rather than an object instance. To remove the Self parameter completely, you have to declare the method as both class and static.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1479
    • Lebeau Software
Re: Troubles with function declaration.
« Reply #4 on: February 12, 2025, 05:04:39 pm »
But then the program will not compile.
I get the following error on   VisaSession.EnableEventHandler(@VisaEventHandler); :

Quote
unit1.pas(97,51) Error: Incompatible type for arg no. 1:
        Got "<procedure variable type of function(LongWord;LongWord;LongWord;Pointer):LongInt of object;StdCall>",
expected "<procedure variable type of function(LongWord;LongWord;LongWord;Pointer):LongInt;StdCall>"

Any proposal on how to fix the issue?


The API in question expects a standalone function for the event handler. So, you cannot use a non-static class method, as its signature won't match due to the hidden Self parameter that holds the object pointer. You can use a static class method instead, but you will lose access to the Self parameter, so you will have to pass the object pointer into the event handler in another way. Presumably via the event handler's event or userHandle parameter (if the API provides a way to pass user-defined data into the event handler). But if not, then you'll have to use a global/thread-local variable, or a thunk, or other similar approach to pass your object pointer into the event handler externally.
« Last Edit: February 12, 2025, 05:13:20 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

CM630

  • Hero Member
  • *****
  • Posts: 1296
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Troubles with function declaration.
« Reply #5 on: February 17, 2025, 11:52:20 am »
Thanks, I think I do not need the self, but anyway, this is too complex for the capacity of my head.
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

cdbc

  • Hero Member
  • *****
  • Posts: 1953
    • http://www.cdbc.dk
Re: Troubles with function declaration.
« Reply #6 on: February 17, 2025, 12:51:40 pm »
Hi
See reply #1, that's the simplest way to do it.
Remember, that in the same unit you have access to the 'Form1' variable, should the need arise... (just make sure it's assigned before you use it)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

CM630

  • Hero Member
  • *****
  • Posts: 1296
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Troubles with function declaration.
« Reply #7 on: February 17, 2025, 01:11:34 pm »
Does it make a difference if I declare it before implementation or I do not declare it at all?
If I do not declare it, the other routines will not see it when the actual function is below them, is there any other difference?
I am not sure if I am clear:

Code: Pascal  [Select][+][-]
  1. procedure procA;
  2. begin
  3.   procB;  //this will not compile, unless ProcB is declared;
  4. end;
  5.  
  6. procedure procB;
  7. begin
  8.   procA;  //this will compile, no matter if ProcA is declared
  9. end;
The big problem is that some odd things happen if I do not declare the event handler as a part of the Form, I already tried this way.
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

cdbc

  • Hero Member
  • *****
  • Posts: 1953
    • http://www.cdbc.dk
Re: Troubles with function declaration.
« Reply #8 on: February 17, 2025, 01:45:26 pm »
Hi
With the callback function, it makes no difference, if it's declared in the interface section or not. It gets called from a library.
With your other cyclic dependency, you'll have to work out a solution, maybe a third func / proc?!?
Regards Benny

edit: without any code whatsoever, it's hard to help you...
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

CM630

  • Hero Member
  • *****
  • Posts: 1296
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Troubles with function declaration.
« Reply #9 on: February 17, 2025, 02:36:48 pm »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

alpine

  • Hero Member
  • *****
  • Posts: 1372
Re: Troubles with function declaration.
« Reply #10 on: February 17, 2025, 03:30:34 pm »
It all started here:
https://forum.lazarus.freepascal.org/index.php?topic=33447.msg547519#msg547519 (reply 6 onwards).
Please, give the full declaration of:
Code: Pascal  [Select][+][-]
  1. VisaSession.EnableEventHandler;
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

CM630

  • Hero Member
  • *****
  • Posts: 1296
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Troubles with function declaration.
« Reply #11 on: February 17, 2025, 03:38:50 pm »
Code: Pascal  [Select][+][-]
  1. procedure TVisaSession.EnableEventHandler(EventHandler: ViHndlr);
  2. begin
  3.   viInstallHandler(fHandle, VI_EVENT_SERVICE_REQ, EventHandler, nil);
  4.   viEnableEvent(fHandle, VI_EVENT_SERVICE_REQ, VI_HNDLR, 0);
  5. end;  

Code: Pascal  [Select][+][-]
  1.   ViHndlr = function(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;
  2. ...
  3.   viInstallHandler: TviInstallHandler;
  4. ... TviInstallHandler   = function(vi: ViSession; eventType: ViEventType; handler: ViHndlr; userHandle: ViAddr): ViStatus; stdcall;
  5.   viEnableEvent: TviEnableEvent;
  6. ...TviEnableEvent = function(vi: ViSession; eventType: ViEventType; mechanism: ViUInt16; context: ViEventFilter): ViStatus; stdcall;
  7. ...
  8.     viInstallHandler:=TviInstallHandler (GetProcedureAddress (DLLHandle, 'viInstallHandler'));
  9.     viEnableEvent:=TviEnableEvent (GetProcedureAddress (DLLHandle, 'viEnableEvent'));
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

Thaddy

  • Hero Member
  • *****
  • Posts: 16652
  • Kallstadt seems a good place to evict Trump to.
Re: Troubles with function declaration.
« Reply #12 on: February 17, 2025, 03:39:32 pm »
Has been covered.
He can simply declare it for the form like so:
Code: Pascal  [Select][+][-]
  1. type TForm1 = class (TCustomForm)
  2.  .....  
  3.     class function VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus;static; stdcall;external;
  4. // external maybe need a name modifier too.
  5. .....
  6. end;
  7. // if it is not external, implement it.
  8. implementation
  9.  
  10. class function TForm1.VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus;static; stdcall;
  11. begin
  12. end;
  13. .......
This way the function is assignment compatible with a normal function.
I wonder what wasn't clear. Should have been closed as fixed weeks ago.
Explicit class function and explicitly marked as static.
That is not rocket science. >:D
Oh, well, my children also do not listen to sound advice... ;) O:-)

I described the generic case, but its principle applies here.
« Last Edit: February 17, 2025, 03:46:34 pm by Thaddy »
But I am sure they don't want the Trumps back...

alpine

  • Hero Member
  • *****
  • Posts: 1372
Re: Troubles with function declaration.
« Reply #13 on: February 17, 2025, 03:42:43 pm »
But why:
Quote
The big problem is that some odd things happen if I do not declare the event handler as a part of the Form, I already tried this way.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Thaddy

  • Hero Member
  • *****
  • Posts: 16652
  • Kallstadt seems a good place to evict Trump to.
Re: Troubles with function declaration.
« Reply #14 on: February 17, 2025, 03:49:46 pm »
He did not implemented it like so, because he does not listen:
Code: Pascal  [Select][+][-]
  1. class function TForm1.VisaEventHandler(vi: ViSession; eventType: ViEventType; event: ViEvent; userHandle: ViAddr): ViStatus; stdcall;static;
This has the same signature as a normal function.
And many already told him so.
It is a matter of taking a deep breath and hope he gets back to his senses.
But I am sure they don't want the Trumps back...

 

TinyPortal © 2005-2018