Last time we discussed the basic idea behind our project. Today we're going to start to get our hands dirty by covering the basic ideas behind the Ptr datatype.
The Ptr data type is used to hold a pointer. For those of you with a C/C++ background, pointers are old-hat. But for anyone who's never had to work with these buggers, here's a bit of education for you. Everything in programming boils down to two different storage mechanisms: value and reference (pointer). A value the data itself. If I say i = 5, then i's value is 5 and somewhere the number 5 is written to memory. A reference is something which points to a value, hence the term pointer. If i is an Integer reference, then i points to a spot in memory where an integer value lives. Diagram time:

In the top part of the diagram, you see a value being stored. i's value lives in some spot in memory. In the bottom part of the diagram, you see a reference being stored. i's value is a memory location, which points to where the true value lives. This is an important distinction to make -- i's *value* is a memory address, and when you go to that memory address, you get to the true value being stored. The act of going to the memory address being referenced is called "dereferencing." You dereference a pointer to get or set the true value.
So the basic fact is that a pointer's value is a memory location which points to some data. In REALbasic, a Ptr is the way to represent a general-purpose reference type. (The other way to specify a reference type is by using the ByRef modifier when defining a parameter). In essence, Ptr is just a simplistic MemoryBlock. However, unlike a MemoryBlock, there's very little hand-holding from a Ptr. You can easily shoot yourself in the foot by using one, and so you should always use caution when dealing with them. There's no bounds checking, no sanity checks of any kind, etc. So they're extremely fast access to memory at the expense of safety.
One nice thing about the Ptr is the fact that you can control how the memory is allocated (and the downside is that you have to worry about how and when to deallocate it). Let's get our feet wet, shall we? We're going to allocate four bytes memory and write the value 5 into it.
We start off by defining a way to allocate the memory. Note that this declare will change for OS X and Linux, but all you'll need to change is the Lib string.
Declare Function malloc Lib "msvcrt" ( bytes as Integer ) as Ptr
Declare Sub free Lib "msvcrt" ( data as Ptr )
// Allocate four bytes of data
dim p as Ptr = malloc( 4 )
// Dereference the pointer and assign the value 5
p.Int32 = 5
// Dereference the pointer and display its value (will be 5)
MsgBox CStr( p.Int32 )
// Display the pointer's value itself (will be a memory address)
MsgBox "&h" + Hex( Int32( p ) )
// Free the memory
free( p )
Ptrs aren't very hard to use -- the way you dereference one is by specifying what type you are going to store into that memory location. The Ptr is automatically dereferenced for you so that you can get/set the data. This maintains REALbasic's strict typesafety rules and helps prevent various coding logic errors. When you want to access the pointer's value itself (not what it references), then you can typecast it to an Int32. This will get you the address that the pointer points to.
Congrats! That's probably your very first time using the Ptr datatype in REALbasic.
One awesome feature to Ptr that I glossed over was the dereferencing ability. You'll notice that I used p.Int32 there. I could have just as easily used p.Single or p.String or even p.SomeStructure. That's a very useful feature which we'll be needing for our project. Another nice thing is that you can also specify an offset (in bytes) to dereference to. Let's modify our example slightly to write out two Integers:
Declare Function malloc Lib "msvcrt" ( bytes as Integer ) as Ptr
Declare Sub free Lib "msvcrt" ( data as Ptr )
// Allocate eight bytes of data
dim p as Ptr = malloc( 8 )
// Dereference the pointer and assign the value 5
p.Int32 = 5
// Dereference the pointer and offset by four bytes to assign another value
p.Int32( 4 ) = 125
// Dereference the pointer and display its value (will be 125)
MsgBox CStr( p.Int32( 4 ) )
// Display the pointer's value itself (will be a memory address)
MsgBox "&h" + Hex( Int32( p ) )
// Free the memory
free( p )
In this example, we dereference the pointer to get to a memory location, and then advance by four more bytes to write out the second value. The diagram for this operation looks like this:

As you can see, the Ptr datatype is very similar to the MemoryBlock. The main differences are:
- Ptr is "to the metal", meaning that it does no bounds checking, no memory management, etc.
- Ptr is faster than MemoryBlock because it doesn't do any hand-holding and it has no method call overhead.
Any questions?
Do you not use soft declares because those functions *will* be there?
Yes -- malloc will always be there, and I'm declaring it against the system's standard lib C libraries, which (AFAIK) should always be there.
Ha--if your system doesn't have malloc and free, I wouldn't know what to say! ;-)
This is pretty nifty. Why is there nothing in the docs about it?
@Adam -- I don't know why there's nothing in the docs about it since docs aren't my area. But I have my guesses.