Is it possible to get the address from a native PureBasic command?

Just starting out? Need help? Post your questions and find answers here.
ricardo_sdl
Enthusiast
Enthusiast
Posts: 108
Joined: Sat Sep 21, 2019 4:24 pm

Is it possible to get the address from a native PureBasic command?

Post by ricardo_sdl »

With a procedure in our source code it is possible to do this:

Code: Select all

procedure dosomething()
;more code here
endprocedure

*Proc = @dosomething();proc now has the address of dosomething
Can we do this?

Code: Select all

*ProcRGBA = @RGBA();well, I tried and it didn't work, is there any other way?
Thanks!
You can check my games at:
https://ricardo-sdl.itch.io/
User avatar
jacdelad
Addict
Addict
Posts: 1418
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: Is it possible to get the address from a native PureBasic command?

Post by jacdelad »

Sorry, I can't help you, but I have a question: For what purpose? A callback?
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
ricardo_sdl
Enthusiast
Enthusiast
Posts: 108
Joined: Sat Sep 21, 2019 4:24 pm

Re: Is it possible to get the address from a native PureBasic command?

Post by ricardo_sdl »

For callbacks yeah. And my other Idea was to create an array with the functions' adresses and use an index to call them for an experiment.
You can check my games at:
https://ricardo-sdl.itch.io/
juergenkulow
Enthusiast
Enthusiast
Posts: 540
Joined: Wed Sep 25, 2019 10:18 am

Re: Is it possible to get the address from a native PureBasic command?

Post by juergenkulow »

Code: Select all

; myRGBA with optimize C Backend 
Procedure.l myRGBA(r.a, g.a, b.a, a.a)
  ProcedureReturn a | b<<8 | g<<16 | r<<24        ; r=(((v_a|(v_b<<8))|(v_g<<16))|(v_r<<24)); return r;
EndProcedure
; 0000000140001000     | 0FB6D2                   | movzx edx,dl                         |
; 0000000140001003     | C1E1 18                  | shl ecx,18                           |
; 0000000140001006     | 45:0FB6C9                | movzx r9d,r9b                        |
; 000000014000100A     | C1E2 10                  | shl edx,10                           |
; 000000014000100D     | 45:0FB6C0                | movzx r8d,r8b                        |
; 0000000140001011     | 09CA                     | Or edx,ecx                           |
; 0000000140001013     | 41:C1E0 08               | shl r8d,8                            |
; 0000000140001017     | 44:09CA                  | Or edx,r9d                           |
; 000000014000101A     | 89D0                     | mov eax,edx                          |
; 000000014000101C     | 44:09C0                  | Or eax,r8d                           |
; 000000014000101F     | C3                       | ret                                  |

*procRGBA=@myRGBA()                               ; p_procrgba=((integer)f_myrgba);
SetClipboardText(Hex(*procRGBA)+" "+Hex(CallFunctionFast(*procRGBA,$47,$11,$12,$ff), #PB_Long))
; 140001000 471112FF
Please ask your questions, because switch on the cognition apparatus decides on the only known life in the universe.Wersten :DDüsseldorf NRW Germany Europe Earth Solar System Flake Bubble Orionarm
Milky Way Local_Group Virgo Supercluster Laniakea Universe
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Is it possible to get the address from a native PureBasic command?

Post by #NULL »

You can use the address of a wrapper function that passes through to the native one. Adds a little overhead (but maybe the c backend optimization can remove the additional call layer) and you have to get the types of return and parameters right, which the documentation is not always clear about. Anyway it works.

Code: Select all

Procedure _RGBA(r, g, b, a)
  ProcedureReturn RGBA(r, g, b, a)
EndProcedure

Procedure getProc()
  ProcedureReturn @_RGBA()
EndProcedure

Prototype.i Proc(r, g, b ,a)

proc.Proc = getProc()

Debug Hex(proc($11, $22, $33, $44)) ; 44332211
User avatar
jacdelad
Addict
Addict
Posts: 1418
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: Is it possible to get the address from a native PureBasic command?

Post by jacdelad »

juergenkulow wrote: Wed Oct 20, 2021 9:01 am

Code: Select all

; myRGBA with optimize C Backend 
Procedure.l myRGBA(r.a, g.a, b.a, a.a)
  ProcedureReturn a | b<<8 | g<<16 | r<<24        ; r=(((v_a|(v_b<<8))|(v_g<<16))|(v_r<<24)); return r;
EndProcedure
; 0000000140001000     | 0FB6D2                   | movzx edx,dl                         |
; 0000000140001003     | C1E1 18                  | shl ecx,18                           |
; 0000000140001006     | 45:0FB6C9                | movzx r9d,r9b                        |
; 000000014000100A     | C1E2 10                  | shl edx,10                           |
; 000000014000100D     | 45:0FB6C0                | movzx r8d,r8b                        |
; 0000000140001011     | 09CA                     | Or edx,ecx                           |
; 0000000140001013     | 41:C1E0 08               | shl r8d,8                            |
; 0000000140001017     | 44:09CA                  | Or edx,r9d                           |
; 000000014000101A     | 89D0                     | mov eax,edx                          |
; 000000014000101C     | 44:09C0                  | Or eax,r8d                           |
; 000000014000101F     | C3                       | ret                                  |

*procRGBA=@myRGBA()                               ; p_procrgba=((integer)f_myrgba);
SetClipboardText(Hex(*procRGBA)+" "+Hex(CallFunctionFast(*procRGBA,$47,$11,$12,$ff), #PB_Long))
; 140001000 471112FF
I'm sure the RGBA() was just mentioned as a placeholder for this question in general.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
ricardo_sdl
Enthusiast
Enthusiast
Posts: 108
Joined: Sat Sep 21, 2019 4:24 pm

Re: Is it possible to get the address from a native PureBasic command?

Post by ricardo_sdl »

Thank you all! The wrapper function will work. I made this test in C:

Code: Select all

#include <stdio.h>
#include <math.h>

int main(int argc, char **argv) {
    float (*sinpointer)(float) = &sinf;

    printf("%f\n", sinpointer(45*3.14159265/180));
    printf("%f\n", sinf(45*3.14159265/180));
}
And we can get the pointer for the sinf function, which is from the standard library. With the C backend maybe PureBasic will allow the same behavior.
You can check my games at:
https://ricardo-sdl.itch.io/
juergenkulow
Enthusiast
Enthusiast
Posts: 540
Joined: Wed Sep 25, 2019 10:18 am

Re: Is it possible to get the address from a native PureBasic command?

Post by juergenkulow »

The PureBasic license explicitly forbids the creation of DLL's whose main function is to serve as a 'wrapper' for PureBasic functions.
ricardo_sdl
Enthusiast
Enthusiast
Posts: 108
Joined: Sat Sep 21, 2019 4:24 pm

Re: Is it possible to get the address from a native PureBasic command?

Post by ricardo_sdl »

juergenkulow wrote: Wed Oct 20, 2021 2:52 pm The PureBasic license explicitly forbids the creation of DLL's whose main function is to serve as a 'wrapper' for PureBasic functions.
It's not my intention to do that. I just want to call them from my code using pointers.
You can check my games at:
https://ricardo-sdl.itch.io/
ricardo_sdl
Enthusiast
Enthusiast
Posts: 108
Joined: Sat Sep 21, 2019 4:24 pm

Re: Is it possible to get the address from a native PureBasic command?

Post by ricardo_sdl »

Just an update:
With a little assembly is possible to get the address of a native command:

Code: Select all

Prototype.d Func(p.d)

Procedure.d MyRadians(Degrees.d)
  ProcedureReturn Degrees * #PI / 180
EndProcedure



*mr.Func = @MyRadians()
Debug *Mr(45)

a.f = Radian(45)
Debug a

*rd.Func = #Null
! LEA    rax,[PB_Radian_DOUBLE]
! PUSH   rax
! POP    qword [p_rd]
b.f = *rd(45)
Debug b
In the example a call to Radian is necessary so the compiler adds the external symbol declaration to PB_Radian_DOUBLE, so we can use it on the inline assembly code to get the function's address and store it on the *rd pointer variable.
You can check my games at:
https://ricardo-sdl.itch.io/
Post Reply