windows x86
pb 5.11
Currently there's no convenient way to call functions from c++ classes in windows x86
and without a compiler directive to differentiate between a com Interface or cpp Interface
we need to either resort to inline asm, use a compiler tool to rewrite the asm or patch the assembly
Interfaces can be made for a c++ classes public members when the functions in the class are declared as virtual functions
So as long as the c++ library exports it's classes constructor functions as extern c you can import the constructor
and assign the result to the interfaces and then call the functions without needing to wrap and recompiling the c++ library.
While the patch adds some overhead and needs to know when and what to patch
the cost of the overhead can be minimized by calling SetCppObj(0) when not in use, when your calling regular functions.
When you need to use an interface to a c++ class you need to call SetCppObj(*activeObject) before calling it's functions.
Code: Select all
;{
CompilerIf #PB_Compiler_OS = #PB_OS_Windows And SizeOf(Integer) = 4
!Macro CALL proc {
!cmp [p_cppobjptr], 0
!je @f
!push edx
!mov edx, dword [p_cppobjptr]
!mov edx, [edx]
!cmp edx, eax
!pop edx
!jne @f
!pop eax
!mov eax, dword [p_cppobjptr]
!mov ecx, eax
!mov eax,[eax]
!@@:
!call proc
!}
Global *cppobjptr
Macro SetCppObj(pInterface)
*cppobjptr = pInterface
EndMacro
;call SetCppOjb with the *objectptr so it knows to patch it to a this call
CompilerEndIf
;}
;you need to call SetCppObj with the active class interface befroe calling the class functions
;you can set it to zero when you are calling regular functions though it's not required
Macro SetCppObj(pInterface)
*cppobjptr = pInterface
EndMacro
Mock up of how to use it
Code: Select all
Interface IrrlichtDevice
Run()
Yield()
Sleep(timeMs, pauseTimer=#False)
GetVideoDriver()
GetFileSystem()
GetGUIEnvironment()
GetSceneManager()
;...
EndInterface
Interface iVideoDriver
EndInterface
Import "Irrlicht.lib"
IrrCreateDevice(deviceType, windowSize, bits, fullscreen, stencilbuffer, vsync, receiver=0) As "_createDevice"
EndImport
Global *IrrDevice.IrrlichtDevice,*videoDriver.IVideoDriver
*IrrDevice.IrrlichtDevice=irrCreateDevice(#EDT_OPENGL,@res,16,#False,#True,#True)
If *IrrDevice
SetCppObj(*IrrDevice) ;set the active c++ class interface so calls can be patched
*videoDriver = *IrrDevice\GetvideoDriver()
SetCppObj(*videoDriver)
*videoDriver\queryFeature(somefeatureflag)
SetCppObj(*IrrDevice)
Repeat
x = *IrrDevice\run()
Until x = 0
EndIf