How to get a C style string from gdextension C api

Godot Version

4.5.2

Question

I am trying to use the gdextension C API, following the tutorial:

I’ve added a C function requiring two strings as parameters, using the exact same patterns shown in the tutorial. I can call the function from gdscript - however It’s not at all clear to me how in my C code I can get a const char* from the struct defined in the example.

The tutorial includes this struct definition:

// The sizes can be obtained from the extension_api.json file.
#ifdef BUILD_32
#define STRING_SIZE 4
#define STRING_NAME_SIZE 4
#else
#define STRING_SIZE 8
#define STRING_NAME_SIZE 8
#endif

...

typedef struct
{
    uint8_t data[STRING_SIZE];
} String;

I’ve copied this to a header file and I’m populating this struct like this:

    constructors.variant_from_string_constructor
        = api.get_variant_from_type_constructor(
            GDEXTENSION_VARIANT_TYPE_STRING);
    constructors.string_from_variant_constructor
        = api.get_variant_to_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING);
inline bool assert_argument_type(const GDExtensionConstVariantPtr *p_args,
                                 GDExtensionCallError *r_error, uint32_t which,
                                 String &out)
{

    GDExtensionVariantType type = api.variant_get_type(p_args[which]);
    if (type != GDEXTENSION_VARIANT_TYPE_STRING)
    {
        r_error->error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
        r_error->expected = GDEXTENSION_VARIANT_TYPE_STRING;
        r_error->argument = which;
        return false;
    }

    constructors.string_from_variant_constructor(
        &out, (GDExtensionVariantPtr)p_args[which]);

    return true;
}

Is there a function I can call to get a const char* out of this struct? It’s not obvious to me from reading the tutorial or browsing gdextension_interface.h how I can do this.

I took another look at gdextension_interface.h and found this typedef:

/**
 * @name string_to_utf8_chars
 * @since 4.1
 *
 * Converts a String to a UTF-8 encoded C string.
 *
 * It doesn't write a null terminator.
 *
 * @param p_self A pointer to the String.
 * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed.
 * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value.
 *
 * @return The resulting encoded string length in characters (not bytes), not including a null terminator.
 */
typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf8Chars)(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length);

Following the pattern from the tutorial, we can get a function pointer and store in the api struct:

    api.string_to_utf8_chars
        = (GDExtensionInterfaceStringToUtf8Chars)p_get_proc_address(
            "string_to_utf8_chars");

Now I just need to hunt down another method for checking string size so I can do the allocation correctly (sigh)

Edit: reading the code explains the code. This function can also be used to get the string length as described in the comment shown above.