Just to clarify some points about CStrings which are really confusing...
"Kevin A. Foss" wrote:
Your program is doing exactly what you told it to do You defined a CString which begins byte1 = H, byte 2 = e, etc., disabled error detection with {$X+} and then called it a string: first 4 bytes is capacity, next 4 bytes current length, then the string bytes
[...]
So take out the {$X+} and use functions CString2String and String2CString where you need them.
Yes, this seems to be exactly what I need. Like I said in my original message it was just a case of me misunderstanding how the different string types cooperate -- and I mistakenly thought that straight CString := String assignments worked in a previous gpc version.
GPC does in fact support assignments of Pascal strings to CStrings and handles them correctly (i.e., sets the CString pointer to the beginning of the text in the string, not to the capacity field, and adds a #0 terminator). That was not the problem in your program. The problem was that a local variable is assigned to a CString, and the variable vanishes after the function returns, and a CString is only a pointer and therefore does not contain a *copy* of the text, but only points to the variable which is gone.
This problem will *not* be solved if you use String2CString -- even though it might appear so, since it works a little different internally, the result is still undefined and could be wrong some day. Correct solutions are e.g. GetMem/FreeMem (or New/Dispose), or declaring the local variable static -- in this case it will not vanish, so the CString will remain valid after the function returns, but only until the local variable is changed (i.e., until the function is called again, in general). Something like this is in fact what some libc routines do, and this is considered quite problematic (more difficult to use from a program, not thread-safe, etc.), therefore also my advice: don't use CStrings here. :-)
Is there a guide to all of the different String functions for conversion and what not?
Not yet, I think, but I as far as CStrings are concerned, String2CString and CString2String should be all that's needed (and the former one only rarely, because of the automatic String 2 CString assignments). Also, the block of functions from CStringLength to CopyCString in the GPC unit deals with CStrings.
When calling a routine (of the RTS or of some C library) that expects a CString parameter, don't worry, just pass it a Pascal string :-) -- unless the function will modify the CString, then things get more difficult...
Frank