Can BlitzMax call a function from a pointer?

BlitzMax Forums/BlitzMax Programming/Can BlitzMax call a function from a pointer?

JoshK(Posted 2006) [#1]
If I get an address to an external function with wglGetProcAddress, can BlitzMax then call that function, and pass an arbitrary number of parameters onto it?


ImaginaryHuman(Posted 2006) [#2]
Turn the address into a Byte Pointer

Turn the Byte Pointer into a Function Pointer, ie Local myfptr()=Byte Ptr(functionaddress)

Set up your function pointer so that it has the same parameters as that function you want to call e.g. Local myfptr(param1:Int,param2:Float)=Byte Ptr(functionaddress)

Then call your function pointer()


JoshK(Posted 2006) [#3]
I think it works.

Declare an OpenGL function to get the pointer to an extension function:
Extern "Win32"
Function wglGetProcAddress:Byte Ptr(lpszProc$z)
EndExtern

Get the pointer to the GL extension function:
Local POINTER_wglSwapInterval : Byte Ptr
POINTER_wglSwapInterval=wglGetProcAddress("wglSwapIntervalEXT")

Declare a function out of the pointer:
Local wglSwapInterval(interval)=Byte Ptr(POINTER_wglSwapInterval)
wglSwapInterval 0

Should the function be declared global so that I can use it anywhere?


ImaginaryHuman(Posted 2006) [#4]
up to you


JoshK(Posted 2006) [#5]
But it has to be global in order to be called anywhere? The BlitzMax method of calling functions is even better than PureBasic.


JoshK(Posted 2006) [#6]
Damn. If I don't build in debug mode I get an unhandled memory exception error when I try to call the function. The pointer is valid, and I can call the function when running in debug mode, and I can see the effect. If it's not in debug mode, it crashes.
Building test
Compiling:test.bmx
flat assembler  version 1.64
3 passes, 13288 bytes.
Linking:test.exe
Executing:test.exe
Unhandled Memory Exception Error
Process complete



Koriolis(Posted 2006) [#7]
You probably need to specify the "win32" calling convention on the pointer, or else when calling through the function pointer the wrong calling convention is used, and the stack is not cleaned up properly.
Something like that is worth a try, and is very likely to correct your problem:
Local wglSwapInterval(interval) "win32" = Byte Ptr(POINTER_wglSwapInterval)



JoshK(Posted 2006) [#8]
That did it.

I actually have the function declared globally, so I just have to set it up once:

Global wglSwapInterval:Int(interval) "Win32"


Thanks!