Page 2 of 2
Re: VCall (Variadic Call) module
Posted: Sun Feb 16, 2020 4:48 pm
by Justin
Hi guys thanks for the help,
mk-soft, your solution does not work, i get an IMA
wilbert, the function is an object method defined as:
Code: Select all
public HRESULT put_Bounds(RECT bounds)
using mk-soft method i define the interface like
Code: Select all
put_Bounds(left_top.q, right_bottom.q)
and
obj\put_Bounds(RectByVal(rc))
but i get an IMA, using .i or .l or splitting the rect in four longs does not work either
Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 8:22 am
by wilbert
Justin wrote:the function is an object method defined as:
Code: Select all
public HRESULT put_Bounds(RECT bounds)
Are you using the 32 or 64 bit version of PureBasic ?
If you are using x64, it might help to change the macro from mk-soft to
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Macro RectByVal(_rect_)
_rect_\top << 32 | (_rect_\left & $ffffffff) ,_rect_\bottom << 32 | (_rect_\right & $ffffffff)
EndMacro
CompilerElse
Macro RectByVal(_rect_)
_rect_\left, _rect_\top, _rect_\right, _rect_\bottom
EndMacro
CompilerEndIf
The original macro doesn't support negative values for left and right on x64.
Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 12:14 pm
by mk-soft
Change your Interface declaration
Code: Select all
Interface iXYZ
; ?
;put_Bounds(RECT bounds)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
put_Bounds(left_top, right_bottom) ; X64
CompilerElseIf
put_Bounds(left, top, right, bottom) ; X86
CompilerEndIf
; ?
EndInterface
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Macro RectByVal(_rect_)
_rect_\top << 32 | _rect_\left ,_rect_\bottom << 32 | _rect_\right
EndMacro
CompilerElse
Macro RectByVal(_rect_)
_rect_\left, _rect_\top, _rect_\right, _rect_\bottom
EndMacro
CompilerEndIf
@wilbert
Left-shift (<<) is no problem. Only right-shift (>>) filled signed bit

Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 2:18 pm
by wilbert
mk-soft wrote:Left-shift (<<) is no problem. Only right-shift (>>) filled signed bit

In this case it is a problem.
If left or right are negative values like for example -50 and -10 and they are casted to 64 bit, the upper 32 bits of those 64 bit values are all 1.
Since the upper 32 bits are already all 1 In such a case, the OR operation will change nothing to that. No matter what value top or bottom is, they will always be -1 when you extract them if the value you combine them with is negative.
Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 3:33 pm
by Justin
Hi wilbert,
i still get an IMA, maybe because it's an object method and not a standard dll api function.
anyways the weird thing is that passing it by reference seems to work.
i plan to post the project when it's finished, you'll be able to check it by yourself.
Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 3:49 pm
by wilbert
Justin wrote:anyways the weird thing is that passing it by reference seems to work.
I'm less familiar with the Windows calling convention compared to macOS.
I see now that the Windows x64 calling convention does mention "Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8 bytes, must be passed by reference." .
https://docs.microsoft.com/en-us/cpp/bu ... ew=vs-2019
So maybe you are right and a C compiler will change it to a reference.
Re: VCall (Variadic Call) module
Posted: Mon Feb 17, 2020 6:19 pm
by Justin
It finally works.
To sum up, as you said in 64 bit works by reference but crashes with the macros.
In 32 bit crashes by reference but works using the macro.
Big thanks to both.
Re: VCall (Variadic Call) module
Posted: Sun Aug 20, 2023 7:31 pm
by infratec
Can someone convert the asm backend assembler additionally to C backend assembler?
I will starting with it, but since I'm not familar with the gcc C asm instructions, it will takes time.
Or can we simulate the VCalls directly in C backend?
Re: VCall (Variadic Call) module
Posted: Mon Aug 21, 2023 5:51 am
by wilbert
infratec wrote: Sun Aug 20, 2023 7:31 pm
Or can we simulate the VCalls directly in C backend?
With the C backend it is faster and easier to call a C function like sprintf directly.
Code: Select all
*result = AllocateMemory(1024)
*format = UTF8("Half the value of PI is = %.3f")
half_pi.d = #PI / 2
!sprintf (p_result, p_format, v_half_pi);
Debug PeekS(*result, -1, #PB_UTF8)