REALbasic used to have some datatypes which were only legal in declares, like CString and PString -- however, in recent history (several releases back, but I forget when), these became first-class datatypes. This means that you can use them outside of the context of declares. However, their use is quite limited outside of declares, so I'd strongly advise against using them as general purpose datatypes. Just use String if you're not going to monkey with declares.
That being said, all of the new string datatypes are essentially a type of Ptr. CString is a pointer to a null-terminated, ANSI C string. WString is a pointer to a null-terminate ANSI wchar_t string. PString is a pointer to a typical Pascal string (up to 255 characters long). CFStringRef is, crazily enough, a CFStringRef (only useful in Carbon and Cocoa), which is an opaque string pointer. This has an interesting ramification when it comes to declares.
Most people coming from VB are well aware of the vbNullString constant that VB uses. This is something that's never really been required in REALbasic parlance... but it does have it's place. That's because a NULL string is vastly different from an empty string when it comes to declares. However, we don't need a fancy constant to represent it -- you can just pass Nil. That's right -- for any of the string datatypes, you just pass Nil if you mean to say "I have no string." It's perfectly legal, and works as you'd expect.
So -- I'll give you one fancy tidbit of information about when you might use these new datatypes in a way that's not strictly declare related. Except... it is declare related. ;-) Callback functions! Here's a great place where you may want to use the externally-sensible datatypes, but not as part of the declare signature itself. Let's take the EnumSystemLocales function as an example. One of its parameter is a function pointer to the callback to be called. This callback takes either a CString or a WString, depending upon which version of the enumeration you're going for. This is a great time to make use of the datatype -- declare your module (or shared) method as taking the appropriate string pointer, and you no longer have to make use of a MemoryBlock for your callback.
It's its! (http://www.cgl.uwaterloo.ca/~csk/its.html)
Cheers! :)
Hey Aaron,
I can think of at least two more cases where they could be useful:
1) Talking to databases other than the built in RB ones.
2) Talking to binary files created by other applications.
I'm sure there are others too.
@Thomas -- Sheesh! I slip up one time... ;-) I typed up this post at 2am, sorry for the typo.
@SerKevin -- those cases may work out too, but a lot of times they won't require you to create methods whose parameter types are the string pointers. You'd just use String as the method parameter type, and then use accessors (like BinaryStream.CString, Ptr.WString, etc) to convert and write out the actual data. This will happen with anything in a binary format: file formats, networking protocols, serial communications, etc.
But the string datatypes aren't so much like Ptr that one can compare instances of any of them to Nil.
Hmm.. no, I don't believe you can compare them against nil, which seems like a slight oversight. Especially since you can get a nil string pointer datatype. Sounds like a good bug report waiting to happen, if you ask me.