Repository: godotengine/godot-cpp (C++)

Issue:
`String::resize()` isn't exposed to GDExtension
### Godot version

v4.1.beta.custom_build.19c1d3c7a

### godot-cpp version

4.1.dev (1bc9ca7)

### System information

Linux

### Issue description

Presently, there is no `String::resize()` method, like we have available in Godot modules.

This is limiting, because it requires that we create a new `char[]`, put the data in there, and then copy from the `char[]` into the string, and then delete it.

This was discovered when trying to compile the `text_server_adv` module in Godot as a GDExtension.

See: https://github.com/godotengine/godot/pull/77532

### Steps to reproduce

```bash
# Assuming you have Godot's source code in 'godot'
cd godot/modules/text_server_adv/gdextension_build
scons
```

### Minimal reproduction project

n/a



Fix (patch):
diff --git a/binding_generator.py b/binding_generator.py
index 6e47e7bcb..0a6580ed4 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -366,6 +366,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
     if class_name == "String":
         result.append("#include <godot_cpp/variant/char_string.hpp>")
         result.append("#include <godot_cpp/variant/char_utils.hpp>")
+        result.append("#include <godot_cpp/classes/global_constants.hpp>")
 
     if class_name == "PackedStringArray":
         result.append("#include <godot_cpp/variant/string.hpp>")
@@ -552,6 +553,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
         result.append("\tChar32String utf32() const;")
         result.append("\tCharWideString wide_string() const;")
         result.append("\tstatic String num_real(double p_num, bool p_trailing = true);")
+        result.append("\tError resize(int p_size);")
 
     if "members" in builtin_api:
         for member in builtin_api["members"]:
diff --git a/gdextension/gdextension_interface.h b/gdextension/gdextension_interface.h
index 43931cc8c..6c05f3988 100644
--- a/gdextension/gdextension_interface.h
+++ b/gdextension/gdextension_interface.h
@@ -1526,6 +1526,25 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringP
  */
 typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionStringPtr p_self, const char32_t *p_b);
 
+/**
+ * @name string_resize
+ * @since 4.2
+ *
+ * Resizes the underlying string data to the given number of characters.
+ *
+ * Space needs to be allocated for the null terminating character ('\0') which
+ * also must be added manually, in order for all string functions to work correctly.
+ *
+ * Warning: This is an error-prone operation - only use it if there's no other
+ * efficient way to accomplish your goal.
+ *
+ * @param p_self A pointer to the String.
+ * @param p_resize The new length for the String.
+ *
+ * @return Error code signifying if the operation successful.
+ */
+typedef GDExtensionInt (*GDExtensionInterfaceStringResize)(GDExtensionStringPtr p_self, GDExtensionInt p_resize);
+
 /* INTERFACE: XMLParser Utilities */
 
 /**
diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp
index 59aa15047..fb89b5562 100644
--- a/include/godot_cpp/godot.hpp
+++ b/include/godot_cpp/godot.hpp
@@ -123,6 +123,7 @@ extern "C" GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_st
 extern "C" GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr;
 extern "C" GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr;
 extern "C" GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str;
+extern "C" GDExtensionInterfaceStringResize gdextension_interface_string_resize;
 extern "C" GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer;
 extern "C" GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer;
 extern "C" GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer;
diff --git a/src/godot.cpp b/src/godot.cpp
index c85667f3b..4a92fad92 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -128,6 +128,7 @@ GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operat
 GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr = nullptr;
 GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr = nullptr;
 GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str = nullptr;
+GDExtensionInterfaceStringResize gdextension_interface_string_resize = nullptr;
 GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer = nullptr;
 GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer = nullptr;
 GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer = nullptr;
@@ -311,6 +312,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	LOAD_PROC_ADDRESS(string_operator_plus_eq_cstr, GDExtensionInterfaceStringOperatorPlusEqCstr);
 	LOAD_PROC_ADDRESS(string_operator_plus_eq_wcstr, GDExtensionInterfaceStringOperatorPlusEqWcstr);
 	LOAD_PROC_ADDRESS(string_operator_plus_eq_c32str, GDExtensionInterfaceStringOperatorPlusEqC32str);
+	LOAD_PROC_ADDRESS(string_resize, GDExtensionInterfaceStringResize);
 	LOAD_PROC_ADDRESS(xml_parser_open_buffer, GDExtensionInterfaceXmlParserOpenBuffer);
 	LOAD_PROC_ADDRESS(file_access_store_buffer, GDExtensionInterfaceFileAccessStoreBuffer);
 	LOAD_PROC_ADDRESS(file_access_get_buffer, GDExtensionInterfaceFileAccessGetBuffer);
diff --git a/src/variant/char_string.cpp b/src/variant/char_string.cpp
index 856037c43..fc8845e81 100644
--- a/src/variant/char_string.cpp
+++ b/src/variant/char_string.cpp
@@ -289,6 +289,10 @@ CharWideString String::wide_string() const {
 	return str;
 }
 
+Error String::resize(int p_size) {
+	return (Error)internal::gdextension_interface_string_resize(_native_ptr(), p_size);
+}
+
 String &String::operator=(const char *p_str) {
 	*this = String(p_str);
 	return *this;