Byte Ptr

BlitzMax Forums/BlitzMax Beginners Area/Byte Ptr

EOF(Posted 2006) [#1]
To date the term "Byte Ptr" still has me confused.

Afterall, its not making a variable point to a 'Byte-sized' variable. or is it?

Can someone explain (in laymans terms) what goes on when you use Bte Ptr?

I've used it in Win32 API functions like this:
Extern "Win32"
    Function InvertRect(hdc%,tREC:Byte Ptr)
End Extern

...

Local r:RECT=New RECT
r.l=x ; r.t=y ; r.r=x+width ; r.b=y+height
InvertRect bufferDC,Byte Ptr(r)

It seems to work without error.
So, is Byte Ptr the same as C's *pointers?

What about Int Ptr, Float Ptr, Varptr, Var, etc ..
Why, where, when, how, would you use these?


Chris C(Posted 2006) [#2]
basicaly all it is, is the adress of an individual byte in memory, for any other type the data that stores the value must have an address, it is the first byte of this data that the byte ptr is pointing to, whether the data is a 1 byte or 1meg long is up to you....


EOF(Posted 2006) [#3]
I think I get what your saying.
Lets take the API InvertRect again as an example.
Here is a description of how the function works:


"InvertRect" (ByVal hdc As Long, lpRect As RECT) As Long

· hDC
Identifies the device context.

· lprc
Points to a RECT structure that contains the logical coordinates of the rectangle to be inverted.


Ok, since lprc needs to point to a RECT structure we do this by using 'Byte Ptr' in BlitzMax:
Extern "Win32"
    Function InvertRect(hdc%,tREC:Byte Ptr)
End Extern


Type RECT
	Field l%, t%, r%, b% ' left top right bottom
End Type

Local r:RECT=New RECT
r.l=x ; r.t=y ; r.r=x+width ; r.b=y+height

InvertRect bufferDC,Byte Ptr(r)
Therefore, InvertRects second parameter will receive the address of the first byte in the RECT structure:


Sound about right to you?


Chris C(Posted 2006) [#4]
yep, funny how a picture explains it better than by brain dead english

if there was a function that needed 2 ints you could for instant send it the byte ptr of rect.r if you wanted to
send it r,b

have I just made things more confusing?


EOF(Posted 2006) [#5]
have I just made things more confusing?
Actually thats pretty well clear ..
Local myrect:RECT=New RECT
myrect.r=123 ; myrect.b=252
InvertRect bufferDC,Byte Ptr(myrect.r)

I think the confusion comes from passing the myrect instance rather that the first field in the myrect type.
Afterall, whats the difference between these two? ..

Type RECT
 Field l%, t%, r%, b% ' left top right bottom
End Type

Local myrect:RECT=New RECT
myrect.l=10 ; myrect.t=20 ; myrect.r=30 ; myrect.b=40

' is this
InvertRect bufferDC,Byte Ptr(myrect)

' the same as this?
InvertRect bufferDC,Byte Ptr(myrect.l)



ImaginaryHuman(Posted 2006) [#6]
Not the same.

The first line is converting the `myrect ptr` into a byte pointer - giving you an address of the first byte of that instance of RECT.

The second line is giving you the pointer to the first byte of the first field within that instance.

You might assume they are the same, they're probably not, I think Max has some other data stored at the beginning of a type instance, so the variables do not begin at 0 offset from the type's location. Or i could be wrong.


Chris C(Posted 2006) [#7]
I think it used to be that way, but they seem to be the same now, which is rather handy...


EOF(Posted 2006) [#8]
Just tested this therory,
Type RECT
	Field l%,r%
End Type

Local myrect:RECT=New RECT
myrect.l=123

Local bp1:Byte Ptr=Byte Ptr(myrect)
Local bp2:Byte Ptr=Byte Ptr(myrect.l)

Print Int(bp1)
Print Int(bp2)

Results:

bp1 = address of myrect structure
bp2 = value stored at myrect.l


Chris C(Posted 2006) [#9]
yeah, i'm not sure that behaviour makes sense!

try getting varptr's for myrect and myrect.l ....

They should be the same address ie bp1


Cajun17(Posted 2006) [#10]
Chris C is right. Check it out.

Type RECT
	Field l:Int,r:Int
End Type

Local myrect:RECT=New RECT
myrect.l=123

Local bp1:Int Ptr=Int Ptr(Byte Ptr(myrect))

bp1[0] = 3444
Print myrect.l