Browse Source

Use StringName in the whole GDExtension API instead of const char *

Emmanuel Leblond 2 years ago
parent
commit
1e8756c94b

+ 25 - 29
core/extension/gdnative_interface.h

@@ -202,21 +202,21 @@ typedef uint64_t (*GDNativeExtensionClassGetRID)(GDExtensionClassInstancePtr p_i
 
 typedef struct {
 	GDNativeVariantType type;
-	const char *name;
-	const char *class_name;
+	GDNativeStringNamePtr name;
+	GDNativeStringNamePtr class_name;
 	uint32_t hint; // Bitfield of `PropertyHint` (defined in `extension_api.json`)
-	const char *hint_string;
+	GDNativeStringPtr hint_string;
 	uint32_t usage; // Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`)
 } GDNativePropertyInfo;
 
 typedef struct {
-	const char *name;
+	GDNativeStringNamePtr name;
 	GDNativePropertyInfo return_value;
 	uint32_t flags; // Bitfield of `GDNativeExtensionClassMethodFlags`
 	int32_t id;
-	GDNativePropertyInfo *arguments;
+	GDNativePropertyInfo *arguments; // array of `argument_count` size
 	uint32_t argument_count;
-	GDNativeVariantPtr default_arguments;
+	GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size
 	uint32_t default_argument_count;
 } GDNativeMethodInfo;
 
@@ -225,13 +225,13 @@ typedef void (*GDNativeExtensionClassFreePropertyList)(GDExtensionClassInstanceP
 typedef GDNativeBool (*GDNativeExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name);
 typedef GDNativeBool (*GDNativeExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);
 typedef void (*GDNativeExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what);
-typedef void (*GDNativeExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDNativeStringPtr p_out);
+typedef void (*GDNativeExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDNativeBool *r_is_valid, GDNativeStringPtr p_out);
 typedef void (*GDNativeExtensionClassReference)(GDExtensionClassInstancePtr p_instance);
 typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
 typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
 typedef GDNativeObjectPtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
 typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
-typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
+typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const GDNativeStringNamePtr p_name);
 
 typedef struct {
 	GDNativeBool is_virtual;
@@ -284,24 +284,21 @@ typedef enum {
 typedef void (*GDNativeExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);
 typedef void (*GDNativeExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
 
-/* passing -1 as argument in the following functions refers to the return type */
-typedef GDNativeVariantType (*GDNativeExtensionClassMethodGetArgumentType)(void *p_method_userdata, int32_t p_argument);
-typedef void (*GDNativeExtensionClassMethodGetArgumentInfo)(void *p_method_userdata, int32_t p_argument, GDNativePropertyInfo *r_info);
-typedef GDNativeExtensionClassMethodArgumentMetadata (*GDNativeExtensionClassMethodGetArgumentMetadata)(void *p_method_userdata, int32_t p_argument);
-
 typedef struct {
-	const char *name;
+	GDNativeStringNamePtr name;
 	void *method_userdata;
 	GDNativeExtensionClassMethodCall call_func;
 	GDNativeExtensionClassMethodPtrCall ptrcall_func;
 	uint32_t method_flags; // Bitfield of `GDNativeExtensionClassMethodFlags`
 	uint32_t argument_count;
 	GDNativeBool has_return_value;
-	GDNativeExtensionClassMethodGetArgumentType get_argument_type_func;
-	GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */
-	GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;
+	GDNativePropertyInfo *return_value_info; // Ignored if `has_return_value` is false
+	GDNativeExtensionClassMethodArgumentMetadata return_value_metadata; // Ignored if `has_return_value` is false
+	/* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */
+	GDNativePropertyInfo *aguments_info; // array of `argument_count` size
+	GDNativeExtensionClassMethodArgumentMetadata *aguments_metadata; // array of `argument_count` size
 	uint32_t default_argument_count;
-	GDNativeVariantPtr *default_arguments;
+	GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size
 } GDNativeExtensionClassMethodInfo;
 
 /* SCRIPT INSTANCE EXTENSION */
@@ -312,7 +309,6 @@ typedef GDNativeBool (*GDNativeExtensionScriptInstanceSet)(GDNativeExtensionScri
 typedef GDNativeBool (*GDNativeExtensionScriptInstanceGet)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);
 typedef const GDNativePropertyInfo *(*GDNativeExtensionScriptInstanceGetPropertyList)(GDNativeExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
 typedef void (*GDNativeExtensionScriptInstanceFreePropertyList)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativePropertyInfo *p_list);
-typedef GDNativeVariantType (*GDNativeExtensionScriptInstanceGetPropertyType)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeBool *r_is_valid);
 
 typedef GDNativeBool (*GDNativeExtensionScriptInstancePropertyCanRevert)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name);
 typedef GDNativeBool (*GDNativeExtensionScriptInstancePropertyGetRevert)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);
@@ -328,7 +324,7 @@ typedef GDNativeBool (*GDNativeExtensionScriptInstanceHasMethod)(GDNativeExtensi
 
 typedef void (*GDNativeExtensionScriptInstanceCall)(GDNativeExtensionScriptInstanceDataPtr p_self, const GDNativeStringNamePtr p_method, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);
 typedef void (*GDNativeExtensionScriptInstanceNotification)(GDNativeExtensionScriptInstanceDataPtr p_instance, int32_t p_what);
-typedef const char *(*GDNativeExtensionScriptInstanceToString)(GDNativeExtensionScriptInstanceDataPtr p_instance, GDNativeBool *r_is_valid);
+typedef void (*GDNativeExtensionScriptInstanceToString)(GDNativeExtensionScriptInstanceDataPtr p_instance, GDNativeBool *r_is_valid, GDNativeStringPtr r_out);
 
 typedef void (*GDNativeExtensionScriptInstanceRefCountIncremented)(GDNativeExtensionScriptInstanceDataPtr p_instance);
 typedef GDNativeBool (*GDNativeExtensionScriptInstanceRefCountDecremented)(GDNativeExtensionScriptInstanceDataPtr p_instance);
@@ -349,7 +345,6 @@ typedef struct {
 	GDNativeExtensionScriptInstanceGet get_func;
 	GDNativeExtensionScriptInstanceGetPropertyList get_property_list_func;
 	GDNativeExtensionScriptInstanceFreePropertyList free_property_list_func;
-	GDNativeExtensionScriptInstanceGetPropertyType get_property_type_func;
 
 	GDNativeExtensionScriptInstancePropertyCanRevert property_can_revert_func;
 	GDNativeExtensionScriptInstancePropertyGetRevert property_get_revert_func;
@@ -546,14 +541,15 @@ typedef struct {
 
 	/* CLASSDB EXTENSION */
 
-	void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
-	void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
-	void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
-	void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
-	void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix);
-	void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix);
-	void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
-	void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */
+	// Provided parameters for `classdb_register_extension_*` can be safely freed once the function returns
+	void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
+	void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
+	void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
+	void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter);
+	void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_group_name, const GDNativeStringPtr p_prefix);
+	void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_subgroup_name, const GDNativeStringPtr p_prefix);
+	void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
+	void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */
 
 	void (*get_library_path)(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path);
 

+ 67 - 42
core/extension/native_extension.cpp

@@ -42,26 +42,37 @@ String NativeExtension::get_extension_list_config_file() {
 class NativeExtensionMethodBind : public MethodBind {
 	GDNativeExtensionClassMethodCall call_func;
 	GDNativeExtensionClassMethodPtrCall ptrcall_func;
-	GDNativeExtensionClassMethodGetArgumentType get_argument_type_func;
-	GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func;
-	GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;
 	void *method_userdata;
 	bool vararg;
+	PropertyInfo return_value_info;
+	GodotTypeInfo::Metadata return_value_metadata;
+	List<PropertyInfo> arguments_info;
+	List<GodotTypeInfo::Metadata> arguments_metadata;
 
 protected:
 	virtual Variant::Type _gen_argument_type(int p_arg) const override {
-		return Variant::Type(get_argument_type_func(method_userdata, p_arg));
+		if (p_arg < 0) {
+			return return_value_info.type;
+		} else {
+			return arguments_info[p_arg].type;
+		}
 	}
 	virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
-		GDNativePropertyInfo pinfo;
-		get_argument_info_func(method_userdata, p_arg, &pinfo);
-		return PropertyInfo(pinfo);
+		if (p_arg < 0) {
+			return return_value_info;
+		} else {
+			return arguments_info[p_arg];
+		}
 	}
 
 public:
 #ifdef DEBUG_METHODS_ENABLED
 	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
-		return GodotTypeInfo::Metadata(get_argument_metadata_func(method_userdata, p_arg));
+		if (p_arg < 0) {
+			return return_value_metadata;
+		} else {
+			return arguments_metadata[p_arg];
+		}
 	}
 #endif
 
@@ -89,10 +100,17 @@ public:
 		method_userdata = p_method_info->method_userdata;
 		call_func = p_method_info->call_func;
 		ptrcall_func = p_method_info->ptrcall_func;
-		get_argument_type_func = p_method_info->get_argument_type_func;
-		get_argument_info_func = p_method_info->get_argument_info_func;
-		get_argument_metadata_func = p_method_info->get_argument_metadata_func;
-		set_name(p_method_info->name);
+		set_name(*reinterpret_cast<StringName *>(p_method_info->name));
+
+		if (p_method_info->has_return_value) {
+			return_value_info = PropertyInfo(*p_method_info->return_value_info);
+			return_value_metadata = GodotTypeInfo::Metadata(p_method_info->return_value_metadata);
+		}
+
+		for (uint32_t i = 0; i < p_method_info->argument_count; i++) {
+			arguments_info.push_back(PropertyInfo(p_method_info->aguments_info[i]));
+			arguments_metadata.push_back(GodotTypeInfo::Metadata(p_method_info->aguments_metadata[i]));
+		}
 
 		set_hint_flags(p_method_info->method_flags);
 
@@ -117,15 +135,15 @@ public:
 
 static GDNativeInterface gdnative_interface;
 
-void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs) {
+void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
+	StringName class_name = *reinterpret_cast<StringName *>(p_class_name);
+	StringName parent_class_name = *reinterpret_cast<StringName *>(p_parent_class_name);
 	ERR_FAIL_COND_MSG(!String(class_name).is_valid_identifier(), "Attempt to register extension class '" + class_name + "', which is not a valid class identifier.");
 	ERR_FAIL_COND_MSG(ClassDB::class_exists(class_name), "Attempt to register extension class '" + class_name + "', which appears to be already registered.");
 
 	Extension *parent_extension = nullptr;
-	StringName parent_class_name = p_parent_class_name;
 
 	if (self->extension_classes.has(parent_class_name)) {
 		parent_extension = &self->extension_classes[parent_class_name];
@@ -172,11 +190,11 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
 
 	ClassDB::register_extension_class(&extension->native_extension);
 }
-void NativeExtension::_register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info) {
+void NativeExtension::_register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	StringName method_name = p_method_info->name;
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	StringName method_name = *reinterpret_cast<const StringName *>(p_method_info->name);
 	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension method '" + String(method_name) + "' for unexisting class '" + class_name + "'.");
 
 	//Extension *extension = &self->extension_classes[class_name];
@@ -186,56 +204,63 @@ void NativeExtension::_register_extension_class_method(const GDNativeExtensionCl
 
 	ClassDB::bind_method_custom(class_name, method);
 }
-void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield) {
+void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + String(p_constant_name) + "' for unexisting class '" + class_name + "'.");
-
-	//Extension *extension = &self->extension_classes[class_name];
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	StringName enum_name = *reinterpret_cast<const StringName *>(p_enum_name);
+	StringName constant_name = *reinterpret_cast<const StringName *>(p_constant_name);
+	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + constant_name + "' for unexisting class '" + class_name + "'.");
 
-	ClassDB::bind_integer_constant(class_name, p_enum_name, p_constant_name, p_constant_value, p_is_bitfield);
+	ClassDB::bind_integer_constant(class_name, enum_name, constant_name, p_constant_value, p_is_bitfield);
 }
 
-void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter) {
+void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	String property_name = p_info->name;
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	StringName setter = *reinterpret_cast<const StringName *>(p_setter);
+	StringName getter = *reinterpret_cast<const StringName *>(p_getter);
+	String property_name = *reinterpret_cast<const StringName *>(p_info->name);
 	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + property_name + "' for unexisting class '" + class_name + "'.");
 
 	//Extension *extension = &self->extension_classes[class_name];
 	PropertyInfo pinfo(*p_info);
 
-	ClassDB::add_property(class_name, pinfo, p_setter, p_getter);
+	ClassDB::add_property(class_name, pinfo, setter, getter);
 }
 
-void NativeExtension::_register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix) {
+void NativeExtension::_register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_group_name, const GDNativeStringPtr p_prefix) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + String(p_group_name) + "' for unexisting class '" + class_name + "'.");
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	String group_name = *reinterpret_cast<const String *>(p_group_name);
+	String prefix = *reinterpret_cast<const String *>(p_prefix);
+	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + group_name + "' for unexisting class '" + class_name + "'.");
 
-	ClassDB::add_property_group(class_name, p_group_name, p_prefix);
+	ClassDB::add_property_group(class_name, group_name, prefix);
 }
 
-void NativeExtension::_register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix) {
+void NativeExtension::_register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringPtr p_subgroup_name, const GDNativeStringPtr p_prefix) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + String(p_subgroup_name) + "' for unexisting class '" + class_name + "'.");
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	String subgroup_name = *reinterpret_cast<const String *>(p_subgroup_name);
+	String prefix = *reinterpret_cast<const String *>(p_prefix);
+	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + subgroup_name + "' for unexisting class '" + class_name + "'.");
 
-	ClassDB::add_property_subgroup(class_name, p_subgroup_name, p_prefix);
+	ClassDB::add_property_subgroup(class_name, subgroup_name, prefix);
 }
 
-void NativeExtension::_register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count) {
+void NativeExtension::_register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
-	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + String(p_signal_name) + "' for unexisting class '" + class_name + "'.");
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
+	StringName signal_name = *reinterpret_cast<const StringName *>(p_signal_name);
+	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + signal_name + "' for unexisting class '" + class_name + "'.");
 
 	MethodInfo s;
-	s.name = p_signal_name;
+	s.name = signal_name;
 	for (int i = 0; i < p_argument_count; i++) {
 		PropertyInfo arg(p_argument_info[i]);
 		s.arguments.push_back(arg);
@@ -243,10 +268,10 @@ void NativeExtension::_register_extension_class_signal(const GDNativeExtensionCl
 	ClassDB::add_signal(class_name, s);
 }
 
-void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name) {
+void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name) {
 	NativeExtension *self = static_cast<NativeExtension *>(p_library);
 
-	StringName class_name = p_class_name;
+	StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
 	ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to unregister unexisting extension class '" + class_name + "'.");
 	Extension *ext = &self->extension_classes[class_name];
 	ERR_FAIL_COND_MSG(ext->native_extension.children.size(), "Attempt to unregister class '" + class_name + "' while other extension classes inherit from it.");

+ 8 - 8
core/extension/native_extension.h

@@ -47,14 +47,14 @@ class NativeExtension : public Resource {
 
 	HashMap<StringName, Extension> extension_classes;
 
-	static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
-	static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
-	static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
-	static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
-	static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix);
-	static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix);
-	static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
-	static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name);
+	static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
+	static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
+	static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
+	static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativePropertyInfo *p_info, const GDNativeStringNamePtr p_setter, const GDNativeStringNamePtr p_getter);
+	static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_group_name, const GDNativeStringNamePtr p_prefix);
+	static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_subgroup_name, const GDNativeStringNamePtr p_prefix);
+	static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
+	static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name);
 	static void _get_library_path(const GDNativeExtensionClassLibraryPtr p_library, GDNativeStringPtr r_path);
 
 	GDNativeInitialization initialization;

+ 4 - 2
core/object/make_virtuals.py

@@ -16,7 +16,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
 		}    \\
 	}\\
     if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
-        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+        /* TODO: C-style cast because GDNativeStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\
+        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDNativeStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDNativeExtensionClassCallVirtual) nullptr;\\
         _gdvirtual_##m_name##_initialized = true;\\
     }\\
 	if (_gdvirtual_##m_name) {\\
@@ -40,7 +41,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\
 	    return _script_instance->has_method(_gdvirtual_##m_name##_sn);\\
 	}\\
     if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
-        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+        /* TODO: C-style cast because GDNativeStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\
+        _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDNativeStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDNativeExtensionClassCallVirtual) nullptr;\\
         _gdvirtual_##m_name##_initialized = true;\\
     }\\
 	if (_gdvirtual_##m_name) {\\

+ 2 - 1
core/object/object.cpp

@@ -808,7 +808,8 @@ String Object::to_string() {
 	}
 	if (_extension && _extension->to_string) {
 		String ret;
-		_extension->to_string(_extension_instance, &ret);
+		GDNativeBool is_valid;
+		_extension->to_string(_extension_instance, &is_valid, &ret);
 		return ret;
 	}
 	return "<" + get_class() + "#" + itos(get_instance_id()) + ">";

+ 17 - 3
core/object/object.h

@@ -192,10 +192,10 @@ struct PropertyInfo {
 
 	explicit PropertyInfo(const GDNativePropertyInfo &pinfo) :
 			type((Variant::Type)pinfo.type),
-			name(pinfo.name),
-			class_name(pinfo.class_name), // can be null
+			name(*reinterpret_cast<StringName *>(pinfo.name)),
+			class_name(*reinterpret_cast<StringName *>(pinfo.class_name)),
 			hint((PropertyHint)pinfo.hint),
-			hint_string(pinfo.hint_string), // can be null
+			hint_string(*reinterpret_cast<String *>(pinfo.hint_string)),
 			usage(pinfo.usage) {}
 
 	bool operator==(const PropertyInfo &p_info) const {
@@ -242,6 +242,20 @@ struct MethodInfo {
 
 	MethodInfo() {}
 
+	explicit MethodInfo(const GDNativeMethodInfo &pinfo) :
+			name(*reinterpret_cast<StringName *>(pinfo.name)),
+			return_val(PropertyInfo(pinfo.return_value)),
+			flags(pinfo.flags),
+			id(pinfo.id) {
+		for (uint32_t j = 0; j < pinfo.argument_count; j++) {
+			arguments.push_back(PropertyInfo(pinfo.arguments[j]));
+		}
+		const Variant *def_values = (const Variant *)pinfo.default_arguments;
+		for (uint32_t j = 0; j < pinfo.default_argument_count; j++) {
+			default_arguments.push_back(def_values[j]);
+		}
+	}
+
 	void _push_params(const PropertyInfo &p_param) {
 		arguments.push_back(p_param);
 	}

+ 16 - 22
core/object/script_language_extension.h

@@ -681,16 +681,21 @@ public:
 		}
 	}
 	virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override {
-		if (native_info->get_property_type_func) {
-			GDNativeBool is_valid = 0;
-			GDNativeVariantType type = native_info->get_property_type_func(instance, (const GDNativeStringNamePtr)&p_name, &is_valid);
-			if (r_is_valid) {
-				*r_is_valid = is_valid != 0;
+		Variant::Type type = Variant::Type::NIL;
+		if (native_info->get_property_list_func) {
+			uint32_t pcount;
+			const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount);
+			for (uint32_t i = 0; i < pcount; i++) {
+				if (p_name == *reinterpret_cast<StringName *>(pinfo->name)) {
+					type = Variant::Type(pinfo->type);
+					break;
+				}
+			}
+			if (native_info->free_property_list_func) {
+				native_info->free_property_list_func(instance, pinfo);
 			}
-
-			return Variant::Type(type);
 		}
-		return Variant::NIL;
+		return type;
 	}
 
 	virtual bool property_can_revert(const StringName &p_name) const override {
@@ -727,19 +732,7 @@ public:
 			uint32_t mcount;
 			const GDNativeMethodInfo *minfo = native_info->get_method_list_func(instance, &mcount);
 			for (uint32_t i = 0; i < mcount; i++) {
-				MethodInfo m;
-				m.name = minfo[i].name;
-				m.flags = minfo[i].flags;
-				m.id = minfo[i].id;
-				m.return_val = PropertyInfo(minfo[i].return_value);
-				for (uint32_t j = 0; j < minfo[i].argument_count; j++) {
-					m.arguments.push_back(PropertyInfo(minfo[i].arguments[j]));
-				}
-				const Variant *def_values = (const Variant *)minfo[i].default_arguments;
-				for (uint32_t j = 0; j < minfo[i].default_argument_count; j++) {
-					m.default_arguments.push_back(def_values[j]);
-				}
-				p_list->push_back(m);
+				p_list->push_back(MethodInfo(minfo[i]));
 			}
 			if (native_info->free_method_list_func) {
 				native_info->free_method_list_func(instance, minfo);
@@ -773,7 +766,8 @@ public:
 	virtual String to_string(bool *r_valid) override {
 		if (native_info->to_string_func) {
 			GDNativeBool valid;
-			String ret = native_info->to_string_func(instance, &valid);
+			String ret;
+			native_info->to_string_func(instance, &valid, reinterpret_cast<GDNativeStringPtr>(&ret));
 			if (r_valid) {
 				*r_valid = valid != 0;
 			}