Author Topic: Does 4.5 & 64 allow you to call a function from it's address or from a variable?  (Read 5249 times)

0 Members and 1 Guest are viewing this topic.

Offline QB64Curious

  • Newbie
  • Posts: 22
    • View Profile
Hi,

One more question, for at least a few days.

Does 64 or 4.5 have some kind of AddressOf( FunctionName$ ), or Eval( FunctionName$ ) that allows us to call a subroutine or function from a variable containing that function name?

So if we have two functions

Code: QB64: [Select]
  1. Function FirstFunction
  2. '...
  3. '...
  4.  
  5. Function SecondFunction
  6. '...
  7. '...
  8.  

, and we put

Code: QB64: [Select]
  1. FunctionName$ = "FirstFunction"

, is there a way of using the variable FunctionName$, to call the function that it references?



Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
No.

Edit: no, unless someone writes some extremely hacky C++.

Offline QB64Curious

  • Newbie
  • Posts: 22
    • View Profile
Huh.  That's a disappointment.

Ok, thanks Luke.

No.

Edit: no, unless someone writes some extremely hacky C++.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
May I request _MEMSUB and _MEMFUNC from Steve and the rest of the qb64 dev team?  A _MEM* variant for function pointers within QB64.  This will allows us to powerfully interface with all kinds of APIs, callback functions, etc.

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
May I request _MEMSUB and _MEMFUNC from Steve and the rest of the qb64 dev team?  A _MEM* variant for function pointers within QB64.  This will allows us to powerfully interface with all kinds of APIs, callback functions, etc.

Would be possible, the C++ part of my example, obtaining the address of a function could be generated automatically during compiling, just as QB64 generates all the other C++ stuff. However it needs to be investigated how to deal best with different return data types (maybe function overloading) and how to savely pass arguments to the (callback) functions.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Here's the hacky method mentioned by luke:
https://qb64forum.alephc.xyz/index.php?topic=4602.msg140102#msg140102
Not quite, that requires the function name to be known as compile time. OP wants to call a function based on a string name known at runtime, which I would imagine looking up symbols in the executable in a fashion similar to loading a dynamically linked library.

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Not quite, that requires the function name to be known as compile time. OP wants to call a function based on a string name known at runtime, which I would imagine looking up symbols in the executable in a fashion similar to loading a dynamically linked library.
Yes one method shall be a name in a variable, but in alternative an address would be ok too, see topic title and OP: AddressOF(Functionname).
However, to look up a functions address by a name given at runtime needs to be some kind of lookup table set up during compiling and some init code (C++ side) at the start of each program which takes the addresses of all user defined SUBs/FUNCs and fill the table respectively to its names.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Regarding some init code, don't know if this method is known to gcc or clang. In my past, when still coding a lot on my old Commodore Amiga, I used MaxonC++ and StormC++. In both a programmer could define init/exit functions in the form _INIT_X_MyFunction and _EXIT_X_MyFunction, where the X ia a number 1 to 9 designating the priority level for linking.

The linker did automatically link those functions into the init/cleanup sections of the final program, hence directly prior branching into main() or when returning/exiting from main(). The linking order is determined by the given level. At init the order is 1 to 9er _INIT functions, at exit respectively the opposite 9er to 1 _EXIT functions.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Isn't this more or less something like what you're wanting? 

Code: QB64: [Select]
  1.     Input "Enter the function name to call =>"; func$
  2.     Print Eval(func$)
  3. Loop Until func$ = ""
  4.  
  5.  
  6. Function Eval (what$)
  7.     Select Case LCase$(what$)
  8.         Case "foo": Eval = Foo
  9.         Case "foo2": Eval = Foo2
  10.         Case "foo3": Eval = Foo3
  11.         Case "foo4": Eval = Foo4
  12.         Case Else: Print "Invalid function name.  You can only call FOO, FOO2, FOO3, or FOO4."
  13.     End Select
  14.  
  15.     Foo = 1
  16.  
  17.     Foo2 = 2
  18.  
  19.     Foo3 = 3
  20.  
  21.     Foo4 = 4
  22.  

A variable is storing the name of the function, and then we're calling the proper function when that variable is set.  Or am I missing something here and the original poster is asking for more than what I'm interpreting from this question?

Quote
is there a way of using the variable FunctionName$, to call the function that it references?
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline QB64Curious

  • Newbie
  • Posts: 22
    • View Profile
Hi Steve,

Yes, something like.  But it doesn't have room for function names not on the list.

FreeBasic appears to have Procedure Pointers, in both the Dos and Windows and Linux versions.  Maybe QB64 can extend to something like this, but we're still stuck with QB 4.5 being what it is.

Thanks everyone for the clarifications, and the C examples.

Isn't this more or less something like what you're wanting? 

Code: QB64: [Select]
  1.     Input "Enter the function name to call =>"; func$
  2.     Print Eval(func$)
  3. Loop Until func$ = ""
  4.  
  5.  
  6. Function Eval (what$)
  7.     Select Case LCase$(what$)
  8.         Case "foo": Eval = Foo
  9.         Case "foo2": Eval = Foo2
  10.         Case "foo3": Eval = Foo3
  11.         Case "foo4": Eval = Foo4
  12.         Case Else: Print "Invalid function name.  You can only call FOO, FOO2, FOO3, or FOO4."
  13.     End Select
  14.  
  15.     Foo = 1
  16.  
  17.     Foo2 = 2
  18.  
  19.     Foo3 = 3
  20.  
  21.     Foo4 = 4
  22.  

A variable is storing the name of the function, and then we're calling the proper function when that variable is set.  Or am I missing something here and the original poster is asking for more than what I'm interpreting from this question?