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. :-D

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. :!: