Page 1 of 1
Basic Pointer Problem -- Pointer treated as simple variable
Posted: Mon Apr 27, 2020 9:35 pm
by glennj.0158
I'm familiar with pointers from C and expected the following to work. It didn't and I don't see my problem.
Code: Select all
Procedure Sample (A.d, B.d, *c.Point )
Debug "Value of *c in Sample() before assignment"
Debug *c
*c = A * B ;Store the result in the variable pointed to by *c
Debug "Value of *c in Sample() after assignment"
Debug *c
EndProcedure
Define Cval.d
Define.Point *C
*C = @CVal ;Pointer *C = Address of (Cval)
Debug "Value of *C in Main()"
Debug *C
Sample (2, 4, *C)
Debug "Value of *C in Main()"
Debug *C
Debug "Value of Cval in Main()"
Debug Cval
End
The Debug output is
Value of *C in Main()
5368967144
Value of *c in Sample() before assignment
5368967144
Value of *c in Sample() after assignment
8
Value of *C in Main()
5368967144
Value of Cval in Main()
0.0
So I get the address into *C in main() but in Sample() the variable *C is treated like a normal variable and not a pointer. I've clearly messed up the declaration of *C as a pointer but I don't see how.
Thanks
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Mon Apr 27, 2020 9:45 pm
by NicTheQuick
There is no dereferencing in Purebasic. If you assign a value to a plain variable or to a pointer variable *c, you only changed the address the pointer points to.
If you want to change the value at the address where the pointer points to, you either have to use PokeD(*c, 123.456) for a single value or in your case you can use the structure fields of the Point structure, which are *c\x and *c\y. But also remember that the Point structure consists of to 16 bit words instead of two doubles. It is a predefined structure from Windows.
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Mon Apr 27, 2020 10:12 pm
by skywalk
I don't know what you are trying to do, but this shows pass ByRef.
Code: Select all
Structure PointD
x.d
y.d
EndStructure
Procedure Sample(A.d, B.d, *c.PointD)
*c\x = A * B
*c\y = A * B
Debug "Value of *c in Sample() after assignment"
Debug *c\x
Debug *c\y
EndProcedure
Define cVal.PointD
Define.PointD *c
*c = @cVal
Debug "Value of *c in Main()"
Debug *c\x
Debug *c\y
Sample(2, 4, *c)
Debug "Value of *c in Main()"
Debug *c\x
Debug *c\y
Debug "Value of cVal in Main()"
Debug cVal\x
Debug cVal\y
Sample(1, 2, @cVal)
Debug "Value of *c in Main()"
Debug *c\x
Debug *c\y
Debug "Value of cVal in Main()"
Debug cVal\x
Debug cVal\y
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Mon Apr 27, 2020 10:13 pm
by Demivec
How about this modified version of your code sample:
Code: Select all
;This structure is already predefined
;Structure Double
; d.d
;EndStructure
Procedure Sample (A.d, B.d, *c.Double )
Debug "Value of *c in Sample() before assignment"
Debug *c/d
*c/d = A * B ;Store the result in the variable pointed to by *c
Debug "Value of *c in Sample() after assignment"
Debug *c/d
EndProcedure
Define Cval.d
Define.Double *C
*C = @CVal ;Pointer *C = Address of (Cval)
Debug "Value of *C in Main()"
Debug *C/d
Sample (2, 4, *C)
Debug "Value of *C in Main()"
Debug *C/d
Debug "Value of Cval in Main()"
Debug Cval
End
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Wed Apr 29, 2020 2:32 am
by glennj.0158
Hi all
What I'm trying for is Call-By-Reference, where the address of an external variable is passed into the procedure and the procedure acts directly on the external variable.
What I was expecting to happen was that by defining *c.Point I would pass the address of the external variable into the procedure and then *c = Value would actually store the value into the location pointed to by the address contained in *c
The example using PokeD(*c, 123.456) {from NicTheQuick} seems like the most direct way to get the effect I was looking for.
Thanks everyone
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Wed Apr 29, 2020 6:30 am
by Little John
In PureBasic,
pass by reference works e.g. like this (no need to use Poke()):
Code: Select all
Procedure ChangeInt (*a.Integer) ; 'Integer' is a predefined structure
*a\i + 3 ; change value of the variable
EndProcedure
Define x.i
x = 7
ChangeInt(@x)
Debug x ; displays 10
With strings it works a bit differently.
Arrays, lists and maps are always passed to procedures by reference anyway.
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Wed Apr 29, 2020 12:19 pm
by mk-soft
Tip and Tricks
VarType 'Any' and 'AnyArray'
Code: Select all
;-TOP
Structure Any
StructureUnion
a.a
b.b
c.c
w.w
u.u
l.l
i.i
q.q
f.f
d.d
EndStructureUnion
EndStructure
Structure AnyArray
StructureUnion
a.a[0]
b.b[0]
c.c[0]
w.w[0]
u.u[0]
l.l[0]
i.i[0]
q.q[0]
f.f[0]
d.d[0]
EndStructureUnion
EndStructure
; ----
Procedure foo(*value.any, Type)
Select Type
Case #PB_Integer
Debug *value\i
Case #PB_Double
Debug *value\d
EndSelect
EndProcedure
Procedure fooArray(*value.AnyArray, Type, uBound)
Protected i
Select Type
Case #PB_Integer
For i = 0 To uBound
Debug *value\i[i]
Next
Case #PB_Double
For i = 0 To uBound
Debug *value\d[i]
Next
Case #PB_String
For i = 0 To uBound
Debug "" + *value\c[i] + " - " + Chr(*value\c[i])
Next
EndSelect
EndProcedure
iVal.i = 100
dblVal.d = 99.1234
foo(@iVal, #PB_Integer)
foo(@dblVal, #PB_Double)
Dim iArray.i(10)
For i = 0 To 10
iArray(i) = i + 100
Next
fooArray(@iArray(), #PB_Integer, ArraySize(iArray()))
sVal.s = "Hello World!"
fooArray(@sVal, #PB_String, Len(sVal) - 1)
Re: Basic Pointer Problem -- Pointer treated as simple varia
Posted: Wed Apr 29, 2020 1:04 pm
by mk-soft
String ByRef is a small problem ...
Link:
https://www.purebasic.fr/english/viewto ... =3&t=74024
Solution
Code: Select all
;- TOP
Procedure foo(*pString.String) ; String ByRef need Pointer to Variable where storage the Pointer to String
*pString\s = "**** " + *pString\s + " ****"
EndProcedure
Define sVal.String
sVal\s = "Hello World!"
foo(@sVal)
Debug sVal\s
; ----
; We need VarPtr
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
Global Text.s = "Hello World!"
Global *pText
VarPtr(Text, *pText) ; Get Pointer to Variable
foo(*pText)
Debug Text