Page 1 of 1
VarPtr for Purebasic
Posted: Thu Nov 14, 2019 8:25 pm
by mk-soft
The VarPtr function returns the start address of the memory area in which a variable is stored. Only for Profis.
Code: Select all
Macro VarPtr(_Var_, _Pointer_)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
lea rax, _Var_
mov _Pointer_, rax
CompilerElse
lea eax, _Var_
mov _Pointer_, eax
CompilerEndIf
DisableASM
EndMacro
Procedure.i MyFunction(*StringByRef.string)
*StringByRef\s + " I Like PureBasic ;)"
EndProcedure
Define text.s, *pText
text = "Hello World!"
VarPtr(text, *pText)
MyFunction(*pText)
; MyFunction(VarPtr(Text))
Debug text
Re: VarPtr for Purebasic
Posted: Thu Nov 14, 2019 9:24 pm
by Josh
A parameter transfer with ByRef would make more sense:
Code: Select all
Procedure MyFunction(ByRef MyText$)
MyText$ + " I Like PureBasic ;)"
EndProcedure
Re: VarPtr for Purebasic
Posted: Thu Nov 14, 2019 9:54 pm
by skywalk
There is an argument to be made a ByRef keyword is similar syntax when PB passes Arrays, Maps, Lists.
Procedure MyFunction(Array myArr(1))
Why not ?
Procedure MyFunction(ByRef myStr$)
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 10:58 am
by NicTheQuick
Interesting. So you can retrieve the Pointer of the variable itself instead of the string in it. That's nice.
Code: Select all
Macro VarPtr(_Var_, _Pointer_)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
lea rax, _Var_
mov _Pointer_, rax
CompilerElse
lea eax, _Var_
mov _Pointer_, eax
CompilerEndIf
DisableASM
EndMacro
Define text.s, *pText
text = "Hello World!"
VarPtr(text, *pText)
Debug "@text = " + StrU(@text, #PB_Quad)
Debug "*pText = " + StrU(*pText, #PB_Quad)
Debug "PeekI(*pText) = " + StrU(PeekI(*pText), #PB_Quad)
In the past I always created a structured string variable to make that happen, but of course that's ugly.
Code: Select all
Procedure.i MyFunction(*StringByRef.string)
*StringByRef\s + " I Like PureBasic ;)"
EndProcedure
Define text.String
text\s = "Hello World"
MyFunction(text)
Debug text\s
Works also with arrays, but is even uglier.
Code: Select all
Procedure.i MyFunction(*StringByRef.string)
*StringByRef\s + " I Like PureBasic ;)"
EndProcedure
Dim text.s(9)
text(5) = "Hello World"
MyFunction(@text() + SizeOf(String) * 5)
Debug text(5)
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 11:05 am
by Danilo
Maybe you could just use the structure 'String' until it is implemented?
Code: Select all
Macro VarPtr(_Var_)
@_Var_
EndMacro
Procedure MyStringFunction(*StringByRef.String)
*StringByRef\s + " I Like PureBasic ;)"
EndProcedure
Procedure MyIntegerFunction(*IntegerByRef.Integer)
*IntegerByRef\i + 12
EndProcedure
Define text.String, x.i
text\s = "Hello World!"
x = 10
MyStringFunction( VarPtr(text) )
MyIntegerFunction( VarPtr(x) )
Debug text\s
Debug x
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 4:11 pm
by skywalk
I thought the point of VarPtr() was to handle ByRef native strings without memory leak?
A structured variable works directly using @.
MyStringFunction(@text)
MyIntegerFunction(@x)
But not a native string?
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 8:37 pm
by mk-soft
@Danilo
Your interpretation of VarPtr is wrong.
VarPtr must return the address to the variable.
Yours is the address back to the value or string.
That's not how it works.
If you change the string, the pointer on the string can change. Therefore you need the address on the variable where the pointer is stored on the string to be able to pass it as ByRef to a procedure.
Edit:
This is actually only required for strings that are created as standard variables (global, define, etc).
For structures with strings and arrays as strings, you already have the variable where the pointer for the string is stored.
See Coding Question :
viewtopic.php?f=13&t=74008
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 9:02 pm
by mk-soft
@skywalk
I thought the point of VarPtr() was to handle ByRef native strings without memory leak? Yes
A structured variable works directly using @. Yes. We have a variable inside the structure with the pointer to string
MyStringFunction(@text) Direct access to String. We can't change strings. Only read
MyIntegerFunction(@x) Direct access to value. No problem. We don't need pointer, because that no changed
Re: VarPtr for Purebasic
Posted: Fri Nov 15, 2019 10:27 pm
by skywalk
Excellent, this should be amplified in the manual.