Cstring in Structures

Here’s kind of an odd thing. I wanted to set up a Structure with space for a flexible string (yeah, I know you aren’t supposed to be able to use it that way, but that’s beside the point) so I added a property as Cstring and it added 4 bytes to the Structure (misleading since it’s really 8 bytes in 64-bit). Just as a test, I added a 4-byte string before it and an UInt16 after it, then used it with a long string for the Cstring. The resulting structure was 14 bytes long in 64-bit and I could convert it to and from its string value with ease.

Except this was true no matter how long I made the string. How could that be? It turns out that adding a Cstring will add the address of that Cstring, not the string itself. If you store it that way and try to load it later, you will crash hard, but it will appear to work as long as the original Cstring is still around.

What’s more, with some simple manipulation, you can change the Cstring in place by using the Structure to get a pointer to it, then using that Ptr to create a MemoryBlock.

I’ll bet none of this was intentional, but could there be some use for this I’ve missed?

strings are ptrs in C :slight_smile:
they’re not “array of bytes”

in C you often see them defined as “char *” or “unsigned char *” which means they are pointers

this IS deliberate

Because some Declares will require or return a structure that contains a Cstring which will really be a Ptr to a Cstring?

If they return a Cstring they are returning a ptr - not an array of bytes

Otherwise they’d have you pass a ptr to a memory buffer and a size to indicate how many bytes they should or can fill in

For instance, on Windows, GetDLLDirectoryA will return the entire DLL search path
It takes a size & ptr to a buffer where the path will be written like

   dim mb as new memoryblock( 4096 )
   soft declare GetDLLDirectoryA lib “Kernel32” ( size as Uint32, buffer as Ptr ) as Uint32
   call GetDLLDirectoryA( 4096, mb )

It stuffs the string data in the block passed in - not a C string (or pointer)

Specifically what declare are you looking at that the struct is needed for ?

I’m not, I just didn’t understand the behavior.

Typically in a declare, you’ll get a block of memory back that consists of a fixed portion followed by the string data itself. The “block” structure will contain a 4-byte (or 8-byte) pointer that usually points to memor just past the end of the fixed block. There you will find the actual string/strings.