浏览代码

C#: Re-write Array, Dictionary, NodePath, String icalls as P/Invoke

Ignacio Roldán Etcheverry 4 年之前
父节点
当前提交
9a51430441

+ 1 - 1
modules/mono/csharp_script.cpp

@@ -109,7 +109,7 @@ Error CSharpLanguage::execute_file(const String &p_path) {
 	return OK;
 }
 
-extern void *godotsharp_pinvoke_funcs[101];
+extern void *godotsharp_pinvoke_funcs[138];
 [[maybe_unused]] volatile void **do_not_strip_godotsharp_pinvoke_funcs;
 
 void CSharpLanguage::init() {

+ 123 - 99
modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs

@@ -2,7 +2,6 @@ using System;
 using System.Collections.Generic;
 using System.Collections;
 using System.Diagnostics.CodeAnalysis;
-using System.Runtime.CompilerServices;
 using Godot.NativeInterop;
 
 namespace Godot.Collections
@@ -22,7 +21,7 @@ namespace Godot.Collections
         /// </summary>
         public Array()
         {
-            godot_icall_Array_Ctor(out NativeValue);
+            NativeValue = NativeFuncs.godotsharp_array_new();
         }
 
         /// <summary>
@@ -48,11 +47,15 @@ namespace Godot.Collections
         public Array(params object[] array) : this()
         {
             if (array == null)
-            {
                 throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
-            }
 
-            godot_icall_Array_Ctor_MonoArray(array, out NativeValue);
+            NativeValue = NativeFuncs.godotsharp_array_new();
+            int length = array.Length;
+
+            Resize(length);
+
+            for (int i = 0; i < length; i++)
+                this[i] = array[i];
         }
 
         private Array(godot_array nativeValueToOwn)
@@ -92,7 +95,7 @@ namespace Godot.Collections
         public Array Duplicate(bool deep = false)
         {
             godot_array newArray;
-            godot_icall_Array_Duplicate(ref NativeValue, deep, out newArray);
+            NativeFuncs.godotsharp_array_duplicate(ref NativeValue, deep, out newArray);
             return CreateTakingOwnershipOfDisposableValue(newArray);
         }
 
@@ -101,18 +104,12 @@ namespace Godot.Collections
         /// </summary>
         /// <param name="newSize">The new size of the array.</param>
         /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
-        public Error Resize(int newSize)
-        {
-            return godot_icall_Array_Resize(ref NativeValue, newSize);
-        }
+        public Error Resize(int newSize) => NativeFuncs.godotsharp_array_resize(ref NativeValue, newSize);
 
         /// <summary>
         /// Shuffles the contents of this <see cref="Array"/> into a random order.
         /// </summary>
-        public void Shuffle()
-        {
-            godot_icall_Array_Shuffle(ref NativeValue);
-        }
+        public void Shuffle() => NativeFuncs.godotsharp_array_shuffle(ref NativeValue);
 
         /// <summary>
         /// Concatenates these two <see cref="Array"/>s.
@@ -122,9 +119,16 @@ namespace Godot.Collections
         /// <returns>A new Godot Array with the contents of both arrays.</returns>
         public static Array operator +(Array left, Array right)
         {
-            godot_array newArray;
-            godot_icall_Array_Concatenate(ref left.NativeValue, ref right.NativeValue, out newArray);
-            return CreateTakingOwnershipOfDisposableValue(newArray);
+            int leftCount = left.Count;
+            int rightCount = right.Count;
+
+            Array newArray = left.Duplicate(deep: false);
+            newArray.Resize(leftCount + rightCount);
+
+            for (int i = 0; i < rightCount; i++)
+                newArray[i + leftCount] = right[i];
+
+            return newArray;
         }
 
         // IList
@@ -137,18 +141,20 @@ namespace Godot.Collections
         /// Returns the object at the given <paramref name="index"/>.
         /// </summary>
         /// <value>The object at the given <paramref name="index"/>.</value>
-        public object this[int index]
+        public unsafe object this[int index]
         {
             get
             {
-                godot_icall_Array_At(ref NativeValue, index, out godot_variant elem);
-                unsafe
-                {
-                    using (elem)
-                        return Marshaling.variant_to_mono_object(&elem);
-                }
+                GetVariantBorrowElementAt(index, out godot_variant borrowElem);
+                return Marshaling.variant_to_mono_object(&borrowElem);
+            }
+            set
+            {
+                if (index < 0 || index >= Count)
+                    throw new IndexOutOfRangeException();
+                godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref NativeValue);
+                ptrw[index] = Marshaling.mono_object_to_variant(value);
             }
-            set => godot_icall_Array_SetAt(ref NativeValue, index, value);
         }
 
         /// <summary>
@@ -157,19 +163,23 @@ namespace Godot.Collections
         /// </summary>
         /// <param name="value">The object to add.</param>
         /// <returns>The new size after adding the object.</returns>
-        public int Add(object value) => godot_icall_Array_Add(ref NativeValue, value);
+        public unsafe int Add(object value)
+        {
+            using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
+            return NativeFuncs.godotsharp_array_add(ref NativeValue, &variantValue);
+        }
 
         /// <summary>
         /// Checks if this <see cref="Array"/> contains the given object.
         /// </summary>
         /// <param name="value">The item to look for.</param>
         /// <returns>Whether or not this array contains the given object.</returns>
-        public bool Contains(object value) => godot_icall_Array_Contains(ref NativeValue, value);
+        public bool Contains(object value) => IndexOf(value) != -1;
 
         /// <summary>
         /// Erases all items from this <see cref="Array"/>.
         /// </summary>
-        public void Clear() => godot_icall_Array_Clear(ref NativeValue);
+        public void Clear() => Resize(0);
 
         /// <summary>
         /// Searches this <see cref="Array"/> for an object
@@ -177,7 +187,11 @@ namespace Godot.Collections
         /// </summary>
         /// <param name="value">The object to search for.</param>
         /// <returns>The index of the object, or -1 if not found.</returns>
-        public int IndexOf(object value) => godot_icall_Array_IndexOf(ref NativeValue, value);
+        public unsafe int IndexOf(object value)
+        {
+            using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
+            return NativeFuncs.godotsharp_array_index_of(ref NativeValue, &variantValue);
+        }
 
         /// <summary>
         /// Inserts a new object at a given position in the array.
@@ -187,20 +201,38 @@ namespace Godot.Collections
         /// </summary>
         /// <param name="index">The index to insert at.</param>
         /// <param name="value">The object to insert.</param>
-        public void Insert(int index, object value) => godot_icall_Array_Insert(ref NativeValue, index, value);
+        public unsafe void Insert(int index, object value)
+        {
+            if (index < 0 || index > Count)
+                throw new IndexOutOfRangeException();
+
+            using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
+            NativeFuncs.godotsharp_array_insert(ref NativeValue, index, &variantValue);
+        }
 
         /// <summary>
         /// Removes the first occurrence of the specified <paramref name="value"/>
         /// from this <see cref="Array"/>.
         /// </summary>
         /// <param name="value">The value to remove.</param>
-        public void Remove(object value) => godot_icall_Array_Remove(ref NativeValue, value);
+        public void Remove(object value)
+        {
+            int index = IndexOf(value);
+            if (index >= 0)
+                RemoveAt(index);
+        }
 
         /// <summary>
         /// Removes an element from this <see cref="Array"/> by index.
         /// </summary>
         /// <param name="index">The index of the element to remove.</param>
-        public void RemoveAt(int index) => godot_icall_Array_RemoveAt(ref NativeValue, index);
+        public void RemoveAt(int index)
+        {
+            if (index < 0 || index > Count)
+                throw new IndexOutOfRangeException();
+
+            NativeFuncs.godotsharp_array_remove_at(ref NativeValue, index);
+        }
 
         // ICollection
 
@@ -209,7 +241,7 @@ namespace Godot.Collections
         /// This is also known as the size or length of the array.
         /// </summary>
         /// <returns>The number of elements.</returns>
-        public int Count => godot_icall_Array_Count(ref NativeValue);
+        public int Count => NativeValue.Size;
 
         object ICollection.SyncRoot => this;
 
@@ -220,17 +252,35 @@ namespace Godot.Collections
         /// untyped C# array, starting at the given index.
         /// </summary>
         /// <param name="array">The array to copy to.</param>
-        /// <param name="index">The index to start at.</param>
-        public void CopyTo(System.Array array, int index)
+        /// <param name="destIndex">The index to start at.</param>
+        public void CopyTo(System.Array array, int destIndex)
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array), "Value cannot be null.");
 
-            if (index < 0)
-                throw new ArgumentOutOfRangeException(nameof(index), "Number was less than the array's lower bound in the first dimension.");
+            if (destIndex < 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(destIndex),
+                    "Number was less than the array's lower bound in the first dimension.");
+            }
 
-            // Internal call may throw ArgumentException
-            godot_icall_Array_CopyTo(ref NativeValue, array, index);
+            int count = Count;
+
+            if (array.Length < (destIndex + count))
+            {
+                throw new ArgumentException(
+                    "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+            }
+
+            unsafe
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    object obj = Marshaling.variant_to_mono_object(&(*NativeValue._p)._arrayVector._ptr[i]);
+                    array.SetValue(obj, destIndex);
+                    destIndex++;
+                }
+            }
         }
 
         // IEnumerable
@@ -253,64 +303,30 @@ namespace Godot.Collections
         /// Converts this <see cref="Array"/> to a string.
         /// </summary>
         /// <returns>A string representation of this array.</returns>
-        public override string ToString()
+        public override unsafe string ToString()
         {
-            return godot_icall_Array_ToString(ref NativeValue);
+            using godot_string str = default;
+            NativeFuncs.godotsharp_array_to_string(ref NativeValue, &str);
+            return Marshaling.mono_string_from_godot(&str);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Ctor(out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Ctor_MonoArray(System.Array array, out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_At(ref godot_array ptr, int index, out godot_variant elem);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_SetAt(ref godot_array ptr, int index, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_Array_Count(ref godot_array ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_Array_Add(ref godot_array ptr, object item);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Clear(ref godot_array ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Concatenate(ref godot_array left, ref godot_array right, out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Array_Contains(ref godot_array ptr, object item);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_CopyTo(ref godot_array ptr, System.Array array, int arrayIndex);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Duplicate(ref godot_array ptr, bool deep, out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_Array_IndexOf(ref godot_array ptr, object item);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_Insert(ref godot_array ptr, int index, object item);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Array_Remove(ref godot_array ptr, object item);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Array_RemoveAt(ref godot_array ptr, int index);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern Error godot_icall_Array_Resize(ref godot_array ptr, int newSize);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern Error godot_icall_Array_Shuffle(ref godot_array ptr);
+        /// <summary>
+        /// The variant returned via the <paramref name="elem"/> parameter is owned by the Array and must not be disposed.
+        /// </summary>
+        internal void GetVariantBorrowElementAt(int index, out godot_variant elem)
+        {
+            if (index < 0 || index >= Count)
+                throw new IndexOutOfRangeException();
+            GetVariantBorrowElementAtUnchecked(index, out elem);
+        }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern string godot_icall_Array_ToString(ref godot_array ptr);
+        /// <summary>
+        /// The variant returned via the <paramref name="elem"/> parameter is owned by the Array and must not be disposed.
+        /// </summary>
+        internal unsafe void GetVariantBorrowElementAtUnchecked(int index, out godot_variant elem)
+        {
+            elem = (*NativeValue._p)._arrayVector._ptr[index];
+        }
     }
 
     internal interface IGenericGodotArray
@@ -451,11 +467,10 @@ namespace Godot.Collections
         {
             get
             {
-                Array.godot_icall_Array_At(ref _underlyingArray.NativeValue, index, out godot_variant elem);
+                _underlyingArray.GetVariantBorrowElementAt(index, out godot_variant borrowElem);
                 unsafe
                 {
-                    using (elem)
-                        return (T)Marshaling.variant_to_mono_object_of_type(&elem, TypeOfElements);
+                    return (T)Marshaling.variant_to_mono_object_of_type(&borrowElem, TypeOfElements);
                 }
             }
             set => _underlyingArray[index] = value;
@@ -546,12 +561,14 @@ namespace Godot.Collections
                 throw new ArgumentNullException(nameof(array), "Value cannot be null.");
 
             if (arrayIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Number was less than the array's lower bound in the first dimension.");
+                throw new ArgumentOutOfRangeException(nameof(arrayIndex),
+                    "Number was less than the array's lower bound in the first dimension.");
 
             int count = _underlyingArray.Count;
 
             if (array.Length < (arrayIndex + count))
-                throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+                throw new ArgumentException(
+                    "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
 
             for (int i = 0; i < count; i++)
             {
@@ -568,7 +585,14 @@ namespace Godot.Collections
         /// <returns>A <see langword="bool"/> indicating success or failure.</returns>
         public bool Remove(T item)
         {
-            return Array.godot_icall_Array_Remove(ref _underlyingArray.NativeValue, item);
+            int index = IndexOf(item);
+            if (index >= 0)
+            {
+                RemoveAt(index);
+                return true;
+            }
+
+            return false;
         }
 
         // IEnumerable<T>

+ 131 - 114
modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Collections;
-using System.Runtime.CompilerServices;
 using Godot.NativeInterop;
 using System.Diagnostics.CodeAnalysis;
 
@@ -23,7 +22,7 @@ namespace Godot.Collections
         /// </summary>
         public Dictionary()
         {
-            godot_icall_Dictionary_Ctor(out NativeValue);
+            NativeValue = NativeFuncs.godotsharp_dictionary_new();
         }
 
         /// <summary>
@@ -77,7 +76,7 @@ namespace Godot.Collections
         public Dictionary Duplicate(bool deep = false)
         {
             godot_dictionary newDictionary;
-            godot_icall_Dictionary_Duplicate(ref NativeValue, deep, out newDictionary);
+            NativeFuncs.godotsharp_dictionary_duplicate(ref NativeValue, deep, out newDictionary);
             return CreateTakingOwnershipOfDisposableValue(newDictionary);
         }
 
@@ -91,7 +90,7 @@ namespace Godot.Collections
             get
             {
                 godot_array keysArray;
-                godot_icall_Dictionary_Keys(ref NativeValue, out keysArray);
+                NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out keysArray);
                 return Array.CreateTakingOwnershipOfDisposableValue(keysArray);
             }
         }
@@ -104,7 +103,7 @@ namespace Godot.Collections
             get
             {
                 godot_array valuesArray;
-                godot_icall_Dictionary_Values(ref NativeValue, out valuesArray);
+                NativeFuncs.godotsharp_dictionary_values(ref NativeValue, out valuesArray);
                 return Array.CreateTakingOwnershipOfDisposableValue(valuesArray);
             }
         }
@@ -112,10 +111,15 @@ namespace Godot.Collections
         private (Array keys, Array values, int count) GetKeyValuePairs()
         {
             godot_array keysArray;
-            godot_array valuesArray;
-            int count = godot_icall_Dictionary_KeyValuePairs(ref NativeValue, out keysArray, out valuesArray);
+            NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out keysArray);
             var keys = Array.CreateTakingOwnershipOfDisposableValue(keysArray);
+
+            godot_array valuesArray;
+            NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out valuesArray);
             var values = Array.CreateTakingOwnershipOfDisposableValue(valuesArray);
+
+            int count = NativeFuncs.godotsharp_dictionary_count(ref NativeValue);
+
             return (keys, values, count);
         }
 
@@ -127,18 +131,28 @@ namespace Godot.Collections
         /// Returns the object at the given <paramref name="key"/>.
         /// </summary>
         /// <value>The object at the given <paramref name="key"/>.</value>
-        public object this[object key]
+        public unsafe object this[object key]
         {
             get
             {
-                godot_icall_Dictionary_GetValue(ref NativeValue, key, out godot_variant value);
-                unsafe
+                using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+                if (NativeFuncs.godotsharp_dictionary_try_get_value(ref NativeValue, &variantKey,
+                    out godot_variant value))
                 {
                     using (value)
                         return Marshaling.variant_to_mono_object(&value);
                 }
+                else
+                {
+                    throw new KeyNotFoundException();
+                }
+            }
+            set
+            {
+                using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+                using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
+                NativeFuncs.godotsharp_dictionary_set_value(ref NativeValue, &variantKey, &variantValue);
             }
-            set => godot_icall_Dictionary_SetValue(ref NativeValue, key, value);
         }
 
         /// <summary>
@@ -147,19 +161,32 @@ namespace Godot.Collections
         /// </summary>
         /// <param name="key">The key at which to add the object.</param>
         /// <param name="value">The object to add.</param>
-        public void Add(object key, object value) => godot_icall_Dictionary_Add(ref NativeValue, key, value);
+        public unsafe void Add(object key, object value)
+        {
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+
+            if (NativeFuncs.godotsharp_dictionary_contains_key(ref NativeValue, &variantKey))
+                throw new ArgumentException("An element with the same key already exists", nameof(key));
+
+            using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
+            NativeFuncs.godotsharp_dictionary_add(ref NativeValue, &variantKey, &variantValue);
+        }
 
         /// <summary>
         /// Erases all items from this <see cref="Dictionary"/>.
         /// </summary>
-        public void Clear() => godot_icall_Dictionary_Clear(ref NativeValue);
+        public void Clear() => NativeFuncs.godotsharp_dictionary_clear(ref NativeValue);
 
         /// <summary>
         /// Checks if this <see cref="Dictionary"/> contains the given key.
         /// </summary>
         /// <param name="key">The key to look for.</param>
         /// <returns>Whether or not this dictionary contains the given key.</returns>
-        public bool Contains(object key) => godot_icall_Dictionary_ContainsKey(ref NativeValue, key);
+        public unsafe bool Contains(object key)
+        {
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+            return NativeFuncs.godotsharp_dictionary_contains_key(ref NativeValue, &variantKey);
+        }
 
         /// <summary>
         /// Gets an enumerator for this <see cref="Dictionary"/>.
@@ -171,7 +198,11 @@ namespace Godot.Collections
         /// Removes an element from this <see cref="Dictionary"/> by key.
         /// </summary>
         /// <param name="key">The key of the element to remove.</param>
-        public void Remove(object key) => godot_icall_Dictionary_RemoveKey(ref NativeValue, key);
+        public unsafe void Remove(object key)
+        {
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+            NativeFuncs.godotsharp_dictionary_remove_key(ref NativeValue, &variantKey);
+        }
 
         // ICollection
 
@@ -184,7 +215,7 @@ namespace Godot.Collections
         /// This is also known as the size or length of the dictionary.
         /// </summary>
         /// <returns>The number of elements.</returns>
-        public int Count => godot_icall_Dictionary_Count(ref NativeValue);
+        public int Count => NativeFuncs.godotsharp_dictionary_count(ref NativeValue);
 
         /// <summary>
         /// Copies the elements of this <see cref="Dictionary"/> to the given
@@ -198,12 +229,14 @@ namespace Godot.Collections
                 throw new ArgumentNullException(nameof(array), "Value cannot be null.");
 
             if (index < 0)
-                throw new ArgumentOutOfRangeException(nameof(index), "Number was less than the array's lower bound in the first dimension.");
+                throw new ArgumentOutOfRangeException(nameof(index),
+                    "Number was less than the array's lower bound in the first dimension.");
 
             var (keys, values, count) = GetKeyValuePairs();
 
             if (array.Length < (index + count))
-                throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+                throw new ArgumentException(
+                    "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
 
             for (int i = 0; i < count; i++)
             {
@@ -241,23 +274,22 @@ namespace Godot.Collections
                     {
                         UpdateEntry();
                     }
+
                     return _entry;
                 }
             }
 
-            private void UpdateEntry()
+            private unsafe void UpdateEntry()
             {
                 _dirty = false;
-                godot_icall_Dictionary_KeyValuePairAt(ref _dictionary.NativeValue, _index, out var vKey, out var vValue);
-                unsafe
+                NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref _dictionary.NativeValue, _index,
+                    out godot_variant key,
+                    out godot_variant value);
+                using (key)
+                using (value)
                 {
-                    using (vKey)
-                    using (vValue)
-                    {
-                        var key = Marshaling.variant_to_mono_object(&vKey);
-                        var value = Marshaling.variant_to_mono_object(&vValue);
-                        _entry = new DictionaryEntry(key, value);
-                    }
+                    _entry = new DictionaryEntry(Marshaling.variant_to_mono_object(&key),
+                        Marshaling.variant_to_mono_object(&value));
                 }
             }
 
@@ -283,61 +315,12 @@ namespace Godot.Collections
         /// Converts this <see cref="Dictionary"/> to a string.
         /// </summary>
         /// <returns>A string representation of this dictionary.</returns>
-        public override string ToString()
+        public override unsafe string ToString()
         {
-            return godot_icall_Dictionary_ToString(ref NativeValue);
+            using godot_string str = default;
+            NativeFuncs.godotsharp_dictionary_to_string(ref NativeValue, &str);
+            return Marshaling.mono_string_from_godot(&str);
         }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Ctor(out godot_dictionary dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_GetValue(ref godot_dictionary ptr, object key, out godot_variant value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_SetValue(ref godot_dictionary ptr, object key, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Keys(ref godot_dictionary ptr, out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Values(ref godot_dictionary ptr, out godot_array dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_Dictionary_KeyValuePairs(ref godot_dictionary ptr, out godot_array keys, out godot_array values);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_KeyValuePairAt(ref godot_dictionary ptr, int index, out godot_variant key, out godot_variant value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Add(ref godot_dictionary ptr, object key, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_Dictionary_Count(ref godot_dictionary ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Clear(ref godot_dictionary ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Dictionary_Contains(ref godot_dictionary ptr, object key, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Dictionary_ContainsKey(ref godot_dictionary ptr, object key);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern void godot_icall_Dictionary_Duplicate(ref godot_dictionary ptr, bool deep, out godot_dictionary dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Dictionary_RemoveKey(ref godot_dictionary ptr, object key);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Dictionary_Remove(ref godot_dictionary ptr, object key, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern bool godot_icall_Dictionary_TryGetValue(ref godot_dictionary ptr, object key, out godot_variant value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern string godot_icall_Dictionary_ToString(ref godot_dictionary ptr);
     }
 
     internal interface IGenericGodotDictionary
@@ -412,7 +395,8 @@ namespace Godot.Collections
         }
 
         // Explicit name to make it very clear
-        internal static Dictionary<TKey, TValue> CreateTakingOwnershipOfDisposableValue(godot_dictionary nativeValueToOwn)
+        internal static Dictionary<TKey, TValue> CreateTakingOwnershipOfDisposableValue(
+            godot_dictionary nativeValueToOwn)
             => new Dictionary<TKey, TValue>(Dictionary.CreateTakingOwnershipOfDisposableValue(nativeValueToOwn));
 
         /// <summary>
@@ -444,11 +428,19 @@ namespace Godot.Collections
         {
             get
             {
-                Dictionary.godot_icall_Dictionary_GetValue(ref _underlyingDict.NativeValue, key, out godot_variant value);
                 unsafe
                 {
-                    using (value)
-                        return (TValue)Marshaling.variant_to_mono_object_of_type(&value, TypeOfValues);
+                    using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+                    if (NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
+                        &variantKey, out godot_variant value))
+                    {
+                        using (value)
+                            return (TValue)Marshaling.variant_to_mono_object_of_type(&value, TypeOfValues);
+                    }
+                    else
+                    {
+                        throw new KeyNotFoundException();
+                    }
                 }
             }
             set => _underlyingDict[key] = value;
@@ -462,7 +454,7 @@ namespace Godot.Collections
             get
             {
                 godot_array keyArray;
-                Dictionary.godot_icall_Dictionary_Keys(ref _underlyingDict.NativeValue, out keyArray);
+                NativeFuncs.godotsharp_dictionary_keys(ref _underlyingDict.NativeValue, out keyArray);
                 return Array<TKey>.CreateTakingOwnershipOfDisposableValue(keyArray);
             }
         }
@@ -475,23 +467,21 @@ namespace Godot.Collections
             get
             {
                 godot_array valuesArray;
-                Dictionary.godot_icall_Dictionary_Values(ref _underlyingDict.NativeValue, out valuesArray);
+                NativeFuncs.godotsharp_dictionary_values(ref _underlyingDict.NativeValue, out valuesArray);
                 return Array<TValue>.CreateTakingOwnershipOfDisposableValue(valuesArray);
             }
         }
 
-        private KeyValuePair<TKey, TValue> GetKeyValuePair(int index)
+        private unsafe KeyValuePair<TKey, TValue> GetKeyValuePair(int index)
         {
-            Dictionary.godot_icall_Dictionary_KeyValuePairAt(ref _underlyingDict.NativeValue, index, out var vKey, out var vValue);
-            unsafe
+            NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref _underlyingDict.NativeValue, index,
+                out godot_variant key,
+                out godot_variant value);
+            using (key)
+            using (value)
             {
-                using (vKey)
-                using (vValue)
-                {
-                    var key = Marshaling.variant_to_mono_object_of_type(&vKey, TypeOfKeys);
-                    var value = Marshaling.variant_to_mono_object_of_type(&vValue, TypeOfValues);
-                    return new KeyValuePair<TKey, TValue>((TKey)key, (TValue)value);
-                }
+                return new KeyValuePair<TKey, TValue>((TKey)Marshaling.variant_to_mono_object(&key),
+                    (TValue)Marshaling.variant_to_mono_object(&value));
             }
         }
 
@@ -520,9 +510,10 @@ namespace Godot.Collections
         /// Removes an element from this <see cref="Dictionary{TKey, TValue}"/> by key.
         /// </summary>
         /// <param name="key">The key of the element to remove.</param>
-        public bool Remove(TKey key)
+        public unsafe bool Remove(TKey key)
         {
-            return Dictionary.godot_icall_Dictionary_RemoveKey(ref _underlyingDict.NativeValue, key);
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+            return NativeFuncs.godotsharp_dictionary_remove_key(ref _underlyingDict.NativeValue, &variantKey);
         }
 
         /// <summary>
@@ -531,18 +522,17 @@ namespace Godot.Collections
         /// <param name="key">The key of the element to get.</param>
         /// <param name="value">The value at the given <paramref name="key"/>.</param>
         /// <returns>If an object was found for the given <paramref name="key"/>.</returns>
-        public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
+        public unsafe bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
         {
-            bool found = Dictionary.godot_icall_Dictionary_TryGetValue(ref _underlyingDict.NativeValue, key, out godot_variant retValue);
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+            bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
+                &variantKey, out godot_variant retValue);
 
-            unsafe
+            using (retValue)
             {
-                using (retValue)
-                {
-                    value = found ?
-                        (TValue)Marshaling.variant_to_mono_object_of_type(&retValue, TypeOfValues) :
-                        default;
-                }
+                value = found ?
+                    (TValue)Marshaling.variant_to_mono_object_of_type(&retValue, TypeOfValues) :
+                    default;
             }
 
             return found;
@@ -572,9 +562,20 @@ namespace Godot.Collections
             _underlyingDict.Clear();
         }
 
-        bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
+        unsafe bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
         {
-            return _underlyingDict.Contains(new KeyValuePair<object, object>(item.Key, item.Value));
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(item.Key);
+            bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
+                &variantKey, out godot_variant retValue);
+
+            using (retValue)
+            {
+                if (!found)
+                    return false;
+
+                using godot_variant variantValue = Marshaling.mono_object_to_variant(item.Value);
+                return NativeFuncs.godotsharp_variant_equals(&variantValue, &retValue);
+            }
         }
 
         /// <summary>
@@ -589,12 +590,14 @@ namespace Godot.Collections
                 throw new ArgumentNullException(nameof(array), "Value cannot be null.");
 
             if (arrayIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Number was less than the array's lower bound in the first dimension.");
+                throw new ArgumentOutOfRangeException(nameof(arrayIndex),
+                    "Number was less than the array's lower bound in the first dimension.");
 
             int count = Count;
 
             if (array.Length < (arrayIndex + count))
-                throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+                throw new ArgumentException(
+                    "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
 
             for (int i = 0; i < count; i++)
             {
@@ -603,9 +606,23 @@ namespace Godot.Collections
             }
         }
 
-        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+        unsafe bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
         {
-            return Dictionary.godot_icall_Dictionary_Remove(ref _underlyingDict.NativeValue, item.Key, item.Value);
+            using godot_variant variantKey = Marshaling.mono_object_to_variant(item.Key);
+            bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
+                &variantKey, out godot_variant retValue);
+
+            using (retValue)
+            {
+                if (!found)
+                    return false;
+
+                using godot_variant variantValue = Marshaling.mono_object_to_variant(item.Value);
+                if (NativeFuncs.godotsharp_variant_equals(&variantValue, &retValue))
+                    return NativeFuncs.godotsharp_dictionary_remove_key(ref _underlyingDict.NativeValue, &variantKey);
+
+                return false;
+            }
         }
 
         // IEnumerable<KeyValuePair<TKey, TValue>>

+ 81 - 40
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs

@@ -171,6 +171,9 @@ namespace Godot.NativeInterop
             NativeFuncs.godotsharp_string_destroy(ref this);
             _ptr = IntPtr.Zero;
         }
+
+        // Size including the null termination character
+        public unsafe int Size => _ptr != IntPtr.Zero ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -262,14 +265,34 @@ namespace Godot.NativeInterop
     // ReSharper disable once InconsistentNaming
     internal struct godot_array : IDisposable
     {
-        internal IntPtr _p;
+        internal unsafe ArrayPrivate* _p;
 
-        public void Dispose()
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct ArrayPrivate
         {
-            if (_p == IntPtr.Zero)
+            private uint _safeRefCount;
+
+            internal VariantVector _arrayVector;
+            // There's more here, but we don't care as we never store this in C#
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct VariantVector
+        {
+            internal IntPtr _writeProxy;
+            internal unsafe godot_variant* _ptr;
+
+            public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+        }
+
+        public unsafe int Size => _p != null ? _p->_arrayVector.Size : 0;
+
+        public unsafe void Dispose()
+        {
+            if (_p == null)
                 return;
             NativeFuncs.godotsharp_array_destroy(ref this);
-            _p = IntPtr.Zero;
+            _p = null;
         }
     }
 
@@ -297,15 +320,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_byte_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe byte* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_byte_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -313,15 +338,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_int32_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe int* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_int32_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *(_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -329,15 +356,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_int64_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe long* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_int64_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -345,15 +374,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_float32_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe float* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_float32_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -361,15 +392,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_float64_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe double* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_float64_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -377,15 +410,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_string_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe godot_string* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_string_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -393,15 +428,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_vector2_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe Vector2* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_vector2_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -409,15 +446,17 @@ namespace Godot.NativeInterop
     internal struct godot_packed_vector3_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe Vector3* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_vector3_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 
     [StructLayout(LayoutKind.Sequential)]
@@ -425,14 +464,16 @@ namespace Godot.NativeInterop
     internal struct godot_packed_color_array : IDisposable
     {
         internal IntPtr _writeProxy;
-        internal IntPtr _ptr;
+        internal unsafe Color* _ptr;
 
-        public void Dispose()
+        public unsafe void Dispose()
         {
-            if (_ptr == IntPtr.Zero)
+            if (_ptr == null)
                 return;
             NativeFuncs.godotsharp_packed_color_array_destroy(ref this);
-            _ptr = IntPtr.Zero;
+            _ptr = null;
         }
+
+        public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
     }
 }

+ 32 - 32
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs

@@ -161,7 +161,8 @@ namespace Godot.NativeInterop
                         if (genericTypeDefinition == typeof(IDictionary<,>))
                             return Variant.Type.Dictionary;
 
-                        if (genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>))
+                        if (genericTypeDefinition == typeof(ICollection<>) ||
+                            genericTypeDefinition == typeof(IEnumerable<>))
                             return Variant.Type.Array;
                     }
                     else if (type == typeof(object))
@@ -430,7 +431,8 @@ namespace Godot.NativeInterop
                         {
                             // TODO: Validate key and value types are compatible with Variant
 #if NET
-                            Collections.IGenericGodotDictionary genericGodotDictionary = IDictionaryToGenericGodotDictionary((dynamic)p_obj);
+                            Collections.IGenericGodotDictionary genericGodotDictionary =
+ IDictionaryToGenericGodotDictionary((dynamic)p_obj);
 #else
                             var genericArguments = type.GetGenericArguments();
 
@@ -441,7 +443,7 @@ namespace Godot.NativeInterop
                                 .MakeGenericMethod(genericArguments[0], genericArguments[1]);
 
                             var genericGodotDictionary = (Collections.IGenericGodotDictionary)method
-                                .Invoke(null, new[] {p_obj});
+                                .Invoke(null, new[] { p_obj });
 #endif
 
                             var godotDict = genericGodotDictionary.UnderlyingDictionary;
@@ -454,7 +456,8 @@ namespace Godot.NativeInterop
                         {
                             // TODO: Validate element type is compatible with Variant
 #if NET
-                            var nativeGodotArray = mono_array_to_Array(System.Runtime.InteropServices.CollectionsMarshal.AsSpan((dynamic)p_obj));
+                            var nativeGodotArray =
+ mono_array_to_Array(System.Runtime.InteropServices.CollectionsMarshal.AsSpan((dynamic)p_obj));
 #else
                             // With .NET Standard we need a package reference for Microsoft.CSharp in order to
                             // use dynamic, so we have this workaround for now until we switch to .NET 5/6.
@@ -623,8 +626,9 @@ namespace Godot.NativeInterop
                                 return VariantUtils.ConvertToUInt64(p_var);
                             default:
                             {
-                                GD.PushError("Attempted to convert Variant to enum value of unsupported underlying type. Name: " +
-                                             type.FullName + " : " + enumUnderlyingType.FullName + ".");
+                                GD.PushError(
+                                    "Attempted to convert Variant to enum value of unsupported underlying type. Name: " +
+                                    type.FullName + " : " + enumUnderlyingType.FullName + ".");
                                 return null;
                             }
                         }
@@ -777,7 +781,7 @@ namespace Godot.NativeInterop
                     VariantUtils.ConvertToDictionary(p_var));
                 return Activator.CreateInstance(fullType,
                     BindingFlags.Public | BindingFlags.Instance, null,
-                    args: new object[] {underlyingDict}, null);
+                    args: new object[] { underlyingDict }, null);
             }
 
             static object variant_to_generic_godot_collections_array(godot_variant* p_var, Type fullType)
@@ -786,7 +790,7 @@ namespace Godot.NativeInterop
                     VariantUtils.ConvertToArray(p_var));
                 return Activator.CreateInstance(fullType,
                     BindingFlags.Public | BindingFlags.Instance, null,
-                    args: new object[] {underlyingArray}, null);
+                    args: new object[] { underlyingArray }, null);
             }
 
             var genericTypeDefinition = type.GetGenericTypeDefinition();
@@ -1010,7 +1014,7 @@ namespace Godot.NativeInterop
 
             const int sizeOfChar32 = 4;
             byte* bytes = (byte*)(*p_string)._ptr;
-            int size = *((int*)(*p_string)._ptr - 1);
+            int size = (*p_string).Size;
             if (size == 0)
                 return string.Empty;
             size -= 1; // zero at the end
@@ -1148,11 +1152,7 @@ namespace Godot.NativeInterop
         public static godot_array mono_array_to_Array(Span<object> p_array)
         {
             if (p_array.IsEmpty)
-            {
-                godot_array ret;
-                Collections.Array.godot_icall_Array_Ctor(out ret);
-                return ret;
-            }
+                return NativeFuncs.godotsharp_array_new();
 
             using var array = new Collections.Array();
             array.Resize(p_array.Length);
@@ -1171,8 +1171,8 @@ namespace Godot.NativeInterop
 
         public static unsafe byte[] PackedByteArray_to_mono_array(godot_packed_byte_array* p_array)
         {
-            byte* buffer = (byte*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            byte* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             var array = new byte[size];
             fixed (byte* dest = array)
                 Buffer.MemoryCopy(buffer, dest, size, size);
@@ -1191,8 +1191,8 @@ namespace Godot.NativeInterop
 
         public static unsafe int[] PackedInt32Array_to_mono_array(godot_packed_int32_array* p_array)
         {
-            int* buffer = (int*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            int* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(int);
             var array = new int[size];
             fixed (int* dest = array)
@@ -1212,8 +1212,8 @@ namespace Godot.NativeInterop
 
         public static unsafe long[] PackedInt64Array_to_mono_array(godot_packed_int64_array* p_array)
         {
-            long* buffer = (long*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            long* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(long);
             var array = new long[size];
             fixed (long* dest = array)
@@ -1233,8 +1233,8 @@ namespace Godot.NativeInterop
 
         public static unsafe float[] PackedFloat32Array_to_mono_array(godot_packed_float32_array* p_array)
         {
-            float* buffer = (float*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            float* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(float);
             var array = new float[size];
             fixed (float* dest = array)
@@ -1254,8 +1254,8 @@ namespace Godot.NativeInterop
 
         public static unsafe double[] PackedFloat64Array_to_mono_array(godot_packed_float64_array* p_array)
         {
-            double* buffer = (double*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            double* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(double);
             var array = new double[size];
             fixed (double* dest = array)
@@ -1275,10 +1275,10 @@ namespace Godot.NativeInterop
 
         public static unsafe string[] PackedStringArray_to_mono_array(godot_packed_string_array* p_array)
         {
-            godot_string* buffer = (godot_string*)(*p_array)._ptr;
+            godot_string* buffer = (*p_array)._ptr;
             if (buffer == null)
                 return new string[] { };
-            int size = *((int*)(*p_array)._ptr - 1);
+            int size = (*p_array).Size;
             var array = new string[size];
             for (int i = 0; i < size; i++)
                 array[i] = mono_string_from_godot(&buffer[i]);
@@ -1308,8 +1308,8 @@ namespace Godot.NativeInterop
 
         public static unsafe Vector2[] PackedVector2Array_to_mono_array(godot_packed_vector2_array* p_array)
         {
-            Vector2* buffer = (Vector2*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            Vector2* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(Vector2);
             var array = new Vector2[size];
             fixed (Vector2* dest = array)
@@ -1329,8 +1329,8 @@ namespace Godot.NativeInterop
 
         public static unsafe Vector3[] PackedVector3Array_to_mono_array(godot_packed_vector3_array* p_array)
         {
-            Vector3* buffer = (Vector3*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            Vector3* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(Vector3);
             var array = new Vector3[size];
             fixed (Vector3* dest = array)
@@ -1350,8 +1350,8 @@ namespace Godot.NativeInterop
 
         public static unsafe Color[] PackedColorArray_to_mono_array(godot_packed_color_array* p_array)
         {
-            Color* buffer = (Color*)(*p_array)._ptr;
-            int size = *((int*)(*p_array)._ptr - 1);
+            Color* buffer = (*p_array)._ptr;
+            int size = (*p_array).Size;
             int sizeInBytes = size * sizeof(Color);
             var array = new Color[size];
             fixed (Color* dest = array)

+ 196 - 28
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs

@@ -17,7 +17,8 @@ namespace Godot.NativeInterop
         // Custom functions
 
         [DllImport(GodotDllName)]
-        public static extern IntPtr godotsharp_method_bind_get_method(ref godot_string_name p_classname, char* p_methodname);
+        public static extern IntPtr godotsharp_method_bind_get_method(ref godot_string_name p_classname,
+            char* p_methodname);
 
 #if NET
         [DllImport(GodotDllName)]
@@ -50,47 +51,60 @@ namespace Godot.NativeInterop
         public static extern void godotsharp_node_path_as_string(godot_string* r_dest, godot_node_path* p_np);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_byte_array godotsharp_packed_byte_array_new_mem_copy(byte* p_src, int p_length);
+        public static extern godot_packed_byte_array godotsharp_packed_byte_array_new_mem_copy(byte* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_int32_array godotsharp_packed_int32_array_new_mem_copy(int* p_src, int p_length);
+        public static extern godot_packed_int32_array godotsharp_packed_int32_array_new_mem_copy(int* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_int64_array godotsharp_packed_int64_array_new_mem_copy(long* p_src, int p_length);
+        public static extern godot_packed_int64_array godotsharp_packed_int64_array_new_mem_copy(long* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_float32_array godotsharp_packed_float32_array_new_mem_copy(float* p_src, int p_length);
+        public static extern godot_packed_float32_array godotsharp_packed_float32_array_new_mem_copy(float* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_float64_array godotsharp_packed_float64_array_new_mem_copy(double* p_src, int p_length);
+        public static extern godot_packed_float64_array godotsharp_packed_float64_array_new_mem_copy(double* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_vector2_array godotsharp_packed_vector2_array_new_mem_copy(Vector2* p_src, int p_length);
+        public static extern godot_packed_vector2_array godotsharp_packed_vector2_array_new_mem_copy(Vector2* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_vector3_array godotsharp_packed_vector3_array_new_mem_copy(Vector3* p_src, int p_length);
+        public static extern godot_packed_vector3_array godotsharp_packed_vector3_array_new_mem_copy(Vector3* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_color_array godotsharp_packed_color_array_new_mem_copy(Color* p_src, int p_length);
+        public static extern godot_packed_color_array godotsharp_packed_color_array_new_mem_copy(Color* p_src,
+            int p_length);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_packed_string_array_add(godot_packed_string_array* r_dest, godot_string* p_element);
+        public static extern void godotsharp_packed_string_array_add(godot_packed_string_array* r_dest,
+            godot_string* p_element);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_callable_new_with_delegate(IntPtr p_delegate_handle, godot_callable* r_callable);
+        public static extern void godotsharp_callable_new_with_delegate(IntPtr p_delegate_handle,
+            godot_callable* r_callable);
 
         [DllImport(GodotDllName)]
-        public static extern bool godotsharp_callable_get_data_for_marshalling(godot_callable* p_callable, IntPtr* r_delegate_handle, IntPtr* r_object, godot_string_name* r_name);
+        public static extern godot_bool godotsharp_callable_get_data_for_marshalling(godot_callable* p_callable,
+            IntPtr* r_delegate_handle, IntPtr* r_object, godot_string_name* r_name);
 
         // GDNative functions
 
         // gdnative.h
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_method_bind_ptrcall(IntPtr p_method_bind, IntPtr p_instance, void** p_args, void* p_ret);
+        public static extern void godotsharp_method_bind_ptrcall(IntPtr p_method_bind, IntPtr p_instance, void** p_args,
+            void* p_ret);
 
         [DllImport(GodotDllName)]
-        public static extern godot_variant godotsharp_method_bind_call(IntPtr p_method_bind, IntPtr p_instance, godot_variant** p_args, int p_arg_count, godot_variant_call_error* p_call_error);
+        public static extern godot_variant godotsharp_method_bind_call(IntPtr p_method_bind, IntPtr p_instance,
+            godot_variant** p_args, int p_arg_count, godot_variant_call_error* p_call_error);
 
         // variant.h
 
@@ -131,34 +145,43 @@ namespace Godot.NativeInterop
         public static extern void godotsharp_variant_new_array(godot_variant* r_dest, godot_array* p_arr);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_byte_array(godot_variant* r_dest, godot_packed_byte_array* p_pba);
+        public static extern void godotsharp_variant_new_packed_byte_array(godot_variant* r_dest,
+            godot_packed_byte_array* p_pba);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_int32_array(godot_variant* r_dest, godot_packed_int32_array* p_pia);
+        public static extern void godotsharp_variant_new_packed_int32_array(godot_variant* r_dest,
+            godot_packed_int32_array* p_pia);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_int64_array(godot_variant* r_dest, godot_packed_int64_array* p_pia);
+        public static extern void godotsharp_variant_new_packed_int64_array(godot_variant* r_dest,
+            godot_packed_int64_array* p_pia);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_float32_array(godot_variant* r_dest, godot_packed_float32_array* p_pra);
+        public static extern void godotsharp_variant_new_packed_float32_array(godot_variant* r_dest,
+            godot_packed_float32_array* p_pra);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_float64_array(godot_variant* r_dest, godot_packed_float64_array* p_pra);
+        public static extern void godotsharp_variant_new_packed_float64_array(godot_variant* r_dest,
+            godot_packed_float64_array* p_pra);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_string_array(godot_variant* r_dest, godot_packed_string_array* p_psa);
+        public static extern void godotsharp_variant_new_packed_string_array(godot_variant* r_dest,
+            godot_packed_string_array* p_psa);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_vector2_array(godot_variant* r_dest, godot_packed_vector2_array* p_pv2a);
+        public static extern void godotsharp_variant_new_packed_vector2_array(godot_variant* r_dest,
+            godot_packed_vector2_array* p_pv2a);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_vector3_array(godot_variant* r_dest, godot_packed_vector3_array* p_pv3a);
+        public static extern void godotsharp_variant_new_packed_vector3_array(godot_variant* r_dest,
+            godot_packed_vector3_array* p_pv3a);
 
         [DllImport(GodotDllName)]
-        public static extern void godotsharp_variant_new_packed_color_array(godot_variant* r_dest, godot_packed_color_array* p_pca);
+        public static extern void godotsharp_variant_new_packed_color_array(godot_variant* r_dest,
+            godot_packed_color_array* p_pca);
 
         [DllImport(GodotDllName)]
-        public static extern bool godotsharp_variant_as_bool(godot_variant* p_self);
+        public static extern godot_bool godotsharp_variant_as_bool(godot_variant* p_self);
 
         [DllImport(GodotDllName)]
         public static extern Int64 godotsharp_variant_as_int(godot_variant* p_self);
@@ -248,23 +271,30 @@ namespace Godot.NativeInterop
         public static extern godot_packed_int64_array godotsharp_variant_as_packed_int64_array(godot_variant* p_self);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_float32_array godotsharp_variant_as_packed_float32_array(godot_variant* p_self);
+        public static extern godot_packed_float32_array godotsharp_variant_as_packed_float32_array(
+            godot_variant* p_self);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_float64_array godotsharp_variant_as_packed_float64_array(godot_variant* p_self);
+        public static extern godot_packed_float64_array godotsharp_variant_as_packed_float64_array(
+            godot_variant* p_self);
 
         [DllImport(GodotDllName)]
         public static extern godot_packed_string_array godotsharp_variant_as_packed_string_array(godot_variant* p_self);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_vector2_array godotsharp_variant_as_packed_vector2_array(godot_variant* p_self);
+        public static extern godot_packed_vector2_array godotsharp_variant_as_packed_vector2_array(
+            godot_variant* p_self);
 
         [DllImport(GodotDllName)]
-        public static extern godot_packed_vector3_array godotsharp_variant_as_packed_vector3_array(godot_variant* p_self);
+        public static extern godot_packed_vector3_array godotsharp_variant_as_packed_vector3_array(
+            godot_variant* p_self);
 
         [DllImport(GodotDllName)]
         public static extern godot_packed_color_array godotsharp_variant_as_packed_color_array(godot_variant* p_self);
 
+        [DllImport(GodotDllName)]
+        public static extern godot_bool godotsharp_variant_equals(godot_variant* p_a, godot_variant* p_b);
+
         // string.h
 
         [DllImport(GodotDllName)]
@@ -282,11 +312,20 @@ namespace Godot.NativeInterop
 
         // array.h
 
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_array_new(godot_array* p_self);
+
         [DllImport(GodotDllName)]
         public static extern void godotsharp_array_new_copy(godot_array* r_dest, godot_array* p_src);
 
+        [DllImport(GodotDllName)]
+        public static extern godot_variant* godotsharp_array_ptrw(ref godot_array p_self);
+
         // dictionary.h
 
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_new(godot_dictionary* p_self);
+
         [DllImport(GodotDllName)]
         public static extern void godotsharp_dictionary_new_copy(godot_dictionary* r_dest, godot_dictionary* p_src);
 
@@ -342,5 +381,134 @@ namespace Godot.NativeInterop
 
         [DllImport(GodotDllName)]
         public static extern void godotsharp_dictionary_destroy(ref godot_dictionary p_self);
+
+        // Array
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_array_add(ref godot_array p_self, godot_variant* p_item);
+
+        [DllImport(GodotDllName)]
+        public static extern void
+            godotsharp_array_duplicate(ref godot_array p_self, godot_bool p_deep, out godot_array r_dest);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_array_index_of(ref godot_array p_self, godot_variant* p_item);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_array_insert(ref godot_array p_self, int p_index, godot_variant* p_item);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_array_remove_at(ref godot_array p_self, int p_index);
+
+        [DllImport(GodotDllName)]
+        public static extern Error godotsharp_array_resize(ref godot_array p_self, int p_new_size);
+
+        [DllImport(GodotDllName)]
+        public static extern Error godotsharp_array_shuffle(ref godot_array p_self);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_array_to_string(ref godot_array p_self, godot_string* r_str);
+
+        // Dictionary
+
+        [DllImport(GodotDllName)]
+        public static extern godot_bool godotsharp_dictionary_try_get_value(ref godot_dictionary p_self,
+            godot_variant* p_key,
+            out godot_variant r_value);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_set_value(ref godot_dictionary p_self, godot_variant* p_key,
+            godot_variant* p_value);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_keys(ref godot_dictionary p_self, out godot_array r_dest);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_values(ref godot_dictionary p_self, out godot_array r_dest);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_dictionary_count(ref godot_dictionary p_self);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_key_value_pair_at(ref godot_dictionary p_self, int p_index,
+            out godot_variant r_key, out godot_variant r_value);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_add(ref godot_dictionary p_self, godot_variant* p_key,
+            godot_variant* p_value);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_clear(ref godot_dictionary p_self);
+
+        [DllImport(GodotDllName)]
+        public static extern godot_bool godotsharp_dictionary_contains_key(ref godot_dictionary p_self,
+            godot_variant* p_key);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_duplicate(ref godot_dictionary p_self, godot_bool p_deep,
+            out godot_dictionary r_dest);
+
+        [DllImport(GodotDllName)]
+        public static extern godot_bool godotsharp_dictionary_remove_key(ref godot_dictionary p_self,
+            godot_variant* p_key);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_dictionary_to_string(ref godot_dictionary p_self, godot_string* r_str);
+
+        // StringExtensions
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_string_md5_buffer(godot_string* p_self,
+            godot_packed_byte_array* r_md5_buffer);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_string_md5_text(godot_string* p_self, godot_string* r_md5_text);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_string_rfind(godot_string* p_self, godot_string* p_what, int p_from);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_string_rfindn(godot_string* p_self, godot_string* p_what, int p_from);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_string_sha256_buffer(godot_string* p_self,
+            godot_packed_byte_array* r_sha256_buffer);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_string_sha256_text(godot_string* p_self, godot_string* r_sha256_text);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_string_simplify_path(godot_string* p_self, godot_string* r_simplified_path);
+
+        // NodePath
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_node_path_get_as_property_path(ref godot_node_path p_self,
+            ref godot_node_path r_dest);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_node_path_get_concatenated_names(ref godot_node_path p_self,
+            godot_string* r_names);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_node_path_get_concatenated_subnames(ref godot_node_path p_self,
+            godot_string* r_subnames);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_node_path_get_name(ref godot_node_path p_self, int p_idx,
+            godot_string* r_name);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_node_path_get_name_count(ref godot_node_path p_self);
+
+        [DllImport(GodotDllName)]
+        public static extern void godotsharp_node_path_get_subname(ref godot_node_path p_self, int p_idx,
+            godot_string* r_subname);
+
+        [DllImport(GodotDllName)]
+        public static extern int godotsharp_node_path_get_subname_count(ref godot_node_path p_self);
+
+        [DllImport(GodotDllName)]
+        public static extern bool godotsharp_node_path_is_absolute(ref godot_node_path p_self);
     }
 }

+ 14 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs

@@ -29,6 +29,13 @@ namespace Godot.NativeInterop
         public static godot_node_path godotsharp_node_path_new_copy(godot_node_path src)
             => godotsharp_node_path_new_copy(&src);
 
+        public static godot_array godotsharp_array_new()
+        {
+            godot_array ret;
+            godotsharp_array_new(&ret);
+            return ret;
+        }
+
         public static godot_array godotsharp_array_new_copy(godot_array* src)
         {
             godot_array ret;
@@ -40,6 +47,13 @@ namespace Godot.NativeInterop
         public static godot_array godotsharp_array_new_copy(godot_array src)
             => godotsharp_array_new_copy(&src);
 
+        public static godot_dictionary godotsharp_dictionary_new()
+        {
+            godot_dictionary ret;
+            godotsharp_dictionary_new(&ret);
+            return ret;
+        }
+
         public static godot_dictionary godotsharp_dictionary_new_copy(godot_dictionary* src)
         {
             godot_dictionary ret;

+ 20 - 36
modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs

@@ -161,7 +161,7 @@ namespace Godot
         public NodePath GetAsPropertyPath()
         {
             godot_node_path propertyPath = default;
-            godot_icall_NodePath_get_as_property_path(ref NativeValue, ref propertyPath);
+            NativeFuncs.godotsharp_node_path_get_as_property_path(ref NativeValue, ref propertyPath);
             return CreateTakingOwnershipOfDisposableValue(propertyPath);
         }
 
@@ -175,9 +175,11 @@ namespace Godot
         /// </code>
         /// </example>
         /// <returns>The names concatenated with <c>/</c>.</returns>
-        public string GetConcatenatedNames()
+        public unsafe string GetConcatenatedNames()
         {
-            return godot_icall_NodePath_get_concatenated_names(ref NativeValue);
+            using godot_string names = default;
+            NativeFuncs.godotsharp_node_path_get_concatenated_names(ref NativeValue, &names);
+            return Marshaling.mono_string_from_godot(&names);
         }
 
         /// <summary>
@@ -191,9 +193,11 @@ namespace Godot
         /// </code>
         /// </example>
         /// <returns>The subnames concatenated with <c>:</c>.</returns>
-        public string GetConcatenatedSubNames()
+        public unsafe string GetConcatenatedSubNames()
         {
-            return godot_icall_NodePath_get_concatenated_subnames(ref NativeValue);
+            using godot_string subNames = default;
+            NativeFuncs.godotsharp_node_path_get_concatenated_subnames(ref NativeValue, &subNames);
+            return Marshaling.mono_string_from_godot(&subNames);
         }
 
         /// <summary>
@@ -209,9 +213,11 @@ namespace Godot
         /// </example>
         /// <param name="idx">The name index.</param>
         /// <returns>The name at the given index <paramref name="idx"/>.</returns>
-        public string GetName(int idx)
+        public unsafe string GetName(int idx)
         {
-            return godot_icall_NodePath_get_name(ref NativeValue, idx);
+            using godot_string name = default;
+            NativeFuncs.godotsharp_node_path_get_name(ref NativeValue, idx, &name);
+            return Marshaling.mono_string_from_godot(&name);
         }
 
         /// <summary>
@@ -222,7 +228,7 @@ namespace Godot
         /// <returns>The number of node names which make up the path.</returns>
         public int GetNameCount()
         {
-            return godot_icall_NodePath_get_name_count(ref NativeValue);
+            return NativeFuncs.godotsharp_node_path_get_name_count(ref NativeValue);
         }
 
         /// <summary>
@@ -230,9 +236,11 @@ namespace Godot
         /// </summary>
         /// <param name="idx">The subname index.</param>
         /// <returns>The subname at the given index <paramref name="idx"/>.</returns>
-        public string GetSubName(int idx)
+        public unsafe string GetSubName(int idx)
         {
-            return godot_icall_NodePath_get_subname(ref NativeValue, idx);
+            using godot_string subName = default;
+            NativeFuncs.godotsharp_node_path_get_subname(ref NativeValue, idx, &subName);
+            return Marshaling.mono_string_from_godot(&subName);
         }
 
         /// <summary>
@@ -243,7 +251,7 @@ namespace Godot
         /// <returns>The number of subnames in the path.</returns>
         public int GetSubNameCount()
         {
-            return godot_icall_NodePath_get_subname_count(ref NativeValue);
+            return NativeFuncs.godotsharp_node_path_get_subname_count(ref NativeValue);
         }
 
         /// <summary>
@@ -255,7 +263,7 @@ namespace Godot
         /// <returns>If the <see cref="NodePath"/> is an absolute path.</returns>
         public bool IsAbsolute()
         {
-            return godot_icall_NodePath_is_absolute(ref NativeValue);
+            return NativeFuncs.godotsharp_node_path_is_absolute(ref NativeValue);
         }
 
         /// <summary>
@@ -263,29 +271,5 @@ namespace Godot
         /// </summary>
         /// <returns>If the <see cref="NodePath"/> is empty.</returns>
         public bool IsEmpty => godot_node_path.IsEmpty(in NativeValue);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void godot_icall_NodePath_get_as_property_path(ref godot_node_path ptr, ref godot_node_path dest);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string godot_icall_NodePath_get_concatenated_names(ref godot_node_path ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string godot_icall_NodePath_get_concatenated_subnames(ref godot_node_path ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string godot_icall_NodePath_get_name(ref godot_node_path ptr, int arg1);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern int godot_icall_NodePath_get_name_count(ref godot_node_path ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string godot_icall_NodePath_get_subname(ref godot_node_path ptr, int arg1);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern int godot_icall_NodePath_get_subname_count(ref godot_node_path ptr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool godot_icall_NodePath_is_absolute(ref godot_node_path ptr);
     }
 }

+ 51 - 42
modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs

@@ -5,6 +5,7 @@ using System.Runtime.CompilerServices;
 using System.Security;
 using System.Text;
 using System.Text.RegularExpressions;
+using Godot.NativeInterop;
 
 namespace Godot
 {
@@ -177,6 +178,7 @@ namespace Godot
                 {
                     return 0;
                 }
+
                 if (from == 0 && to == len)
                 {
                     str = instance;
@@ -471,7 +473,8 @@ namespace Godot
         /// <returns>The starting position of the substring, or -1 if not found.</returns>
         public static int Find(this string instance, string what, int from = 0, bool caseSensitive = true)
         {
-            return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+            return instance.IndexOf(what, from,
+                caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
         }
 
         /// <summary>
@@ -490,7 +493,8 @@ namespace Godot
         {
             // TODO: Could be more efficient if we get a char version of `IndexOf`.
             // See https://github.com/dotnet/runtime/issues/44116
-            return instance.IndexOf(what.ToString(), from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+            return instance.IndexOf(what.ToString(), from,
+                caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
         }
 
         /// <summary>Find the last occurrence of a substring.</summary>
@@ -519,7 +523,8 @@ namespace Godot
         /// <returns>The starting position of the substring, or -1 if not found.</returns>
         public static int FindLast(this string instance, string what, int from, bool caseSensitive = true)
         {
-            return instance.LastIndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+            return instance.LastIndexOf(what, from,
+                caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
         }
 
         /// <summary>
@@ -804,6 +809,7 @@ namespace Godot
                 {
                     match = instance[source] == text[target];
                 }
+
                 if (match)
                 {
                     source++;
@@ -1015,15 +1021,18 @@ namespace Godot
             switch (expr[0])
             {
                 case '*':
-                    return ExprMatch(instance, expr.Substring(1), caseSensitive) || (instance.Length > 0 && ExprMatch(instance.Substring(1), expr, caseSensitive));
+                    return ExprMatch(instance, expr.Substring(1), caseSensitive) || (instance.Length > 0 &&
+                        ExprMatch(instance.Substring(1), expr, caseSensitive));
                 case '?':
-                    return instance.Length > 0 && instance[0] != '.' && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
+                    return instance.Length > 0 && instance[0] != '.' &&
+                           ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
                 default:
                     if (instance.Length == 0)
                         return false;
                     if (caseSensitive)
                         return instance[0] == expr[0];
-                    return (char.ToUpper(instance[0]) == char.ToUpper(expr[0])) && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
+                    return (char.ToUpper(instance[0]) == char.ToUpper(expr[0])) &&
+                           ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
             }
         }
 
@@ -1068,28 +1077,28 @@ namespace Godot
         /// <seealso cref="MD5Text(string)"/>
         /// <param name="instance">The string to hash.</param>
         /// <returns>The MD5 hash of the string.</returns>
-        public static byte[] MD5Buffer(this string instance)
+        public static unsafe byte[] MD5Buffer(this string instance)
         {
-            return godot_icall_String_md5_buffer(instance);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_packed_byte_array md5Buffer = default;
+            NativeFuncs.godotsharp_string_md5_buffer(&instanceStr, &md5Buffer);
+            return Marshaling.PackedByteArray_to_mono_array(&md5Buffer);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern byte[] godot_icall_String_md5_buffer(string str);
-
         /// <summary>
         /// Returns the MD5 hash of the string as a string.
         /// </summary>
         /// <seealso cref="MD5Buffer(string)"/>
         /// <param name="instance">The string to hash.</param>
         /// <returns>The MD5 hash of the string.</returns>
-        public static string MD5Text(this string instance)
+        public static unsafe string MD5Text(this string instance)
         {
-            return godot_icall_String_md5_text(instance);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_string md5Text = default;
+            NativeFuncs.godotsharp_string_md5_text(&instanceStr, &md5Text);
+            return Marshaling.mono_string_from_godot(&md5Text);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern string godot_icall_String_md5_text(string str);
-
         /// <summary>
         /// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
         /// </summary>
@@ -1242,14 +1251,13 @@ namespace Godot
         /// <param name="what">The substring to search in the string.</param>
         /// <param name="from">The position at which to start searching.</param>
         /// <returns>The position at which the substring was found, or -1 if not found.</returns>
-        public static int RFind(this string instance, string what, int from = -1)
+        public static unsafe int RFind(this string instance, string what, int from = -1)
         {
-            return godot_icall_String_rfind(instance, what, from);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_string whatStr = Marshaling.mono_string_to_godot(instance);
+            return NativeFuncs.godotsharp_string_rfind(&instanceStr, &whatStr, from);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_String_rfind(string str, string what, int from);
-
         /// <summary>
         /// Perform a search for a substring, but start from the end of the string instead of the beginning.
         /// Also search case-insensitive.
@@ -1259,14 +1267,13 @@ namespace Godot
         /// <param name="what">The substring to search in the string.</param>
         /// <param name="from">The position at which to start searching.</param>
         /// <returns>The position at which the substring was found, or -1 if not found.</returns>
-        public static int RFindN(this string instance, string what, int from = -1)
+        public static unsafe int RFindN(this string instance, string what, int from = -1)
         {
-            return godot_icall_String_rfindn(instance, what, from);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_string whatStr = Marshaling.mono_string_to_godot(instance);
+            return NativeFuncs.godotsharp_string_rfindn(&instanceStr, &whatStr, from);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern int godot_icall_String_rfindn(string str, string what, int from);
-
         /// <summary>
         /// Returns the right side of the string from a given position.
         /// </summary>
@@ -1319,28 +1326,28 @@ namespace Godot
         /// <seealso cref="SHA256Text(string)"/>
         /// <param name="instance">The string to hash.</param>
         /// <returns>The SHA-256 hash of the string.</returns>
-        public static byte[] SHA256Buffer(this string instance)
+        public static unsafe byte[] SHA256Buffer(this string instance)
         {
-            return godot_icall_String_sha256_buffer(instance);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_packed_byte_array sha256Buffer = default;
+            NativeFuncs.godotsharp_string_sha256_buffer(&instanceStr, &sha256Buffer);
+            return Marshaling.PackedByteArray_to_mono_array(&sha256Buffer);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern byte[] godot_icall_String_sha256_buffer(string str);
-
         /// <summary>
         /// Returns the SHA-256 hash of the string as a string.
         /// </summary>
         /// <seealso cref="SHA256Buffer(string)"/>
         /// <param name="instance">The string to hash.</param>
         /// <returns>The SHA-256 hash of the string.</returns>
-        public static string SHA256Text(this string instance)
+        public static unsafe string SHA256Text(this string instance)
         {
-            return godot_icall_String_sha256_text(instance);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_string sha256Text = default;
+            NativeFuncs.godotsharp_string_sha256_text(&instanceStr, &sha256Text);
+            return Marshaling.mono_string_from_godot(&sha256Text);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern string godot_icall_String_sha256_text(string str);
-
         /// <summary>
         /// Returns the similarity index of the text compared to this string.
         /// 1 means totally similar and 0 means totally dissimilar.
@@ -1355,6 +1362,7 @@ namespace Godot
                 // Equal strings are totally similar
                 return 1.0f;
             }
+
             if (instance.Length < 2 || text.Length < 2)
             {
                 // No way to calculate similarity without a single bigram
@@ -1388,14 +1396,14 @@ namespace Godot
         /// <summary>
         /// Returns a simplified canonical path.
         /// </summary>
-        public static string SimplifyPath(this string instance)
+        public static unsafe string SimplifyPath(this string instance)
         {
-            return godot_icall_String_simplify_path(instance);
+            using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
+            using godot_string simplifiedPath = default;
+            NativeFuncs.godotsharp_string_simplify_path(&instanceStr, &simplifiedPath);
+            return Marshaling.mono_string_from_godot(&simplifiedPath);
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        internal static extern string godot_icall_String_simplify_path(string str);
-
         /// <summary>
         /// Split the string by a divisor string, return an array of the substrings.
         /// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
@@ -1409,7 +1417,8 @@ namespace Godot
         /// <returns>The array of strings split from the string.</returns>
         public static string[] Split(this string instance, string divisor, bool allowEmpty = true)
         {
-            return instance.Split(new[] { divisor }, allowEmpty ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries);
+            return instance.Split(new[] { divisor },
+                allowEmpty ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries);
         }
 
         /// <summary>

+ 0 - 300
modules/mono/glue/collections_glue.cpp

@@ -1,300 +0,0 @@
-/*************************************************************************/
-/*  collections_glue.cpp                                                 */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include <mono/metadata/exception.h>
-
-#include "core/variant/array.h"
-
-#include "../mono_gd/gd_mono_cache.h"
-#include "../mono_gd/gd_mono_class.h"
-#include "../mono_gd/gd_mono_marshal.h"
-#include "../mono_gd/gd_mono_utils.h"
-
-void godot_icall_Array_Ctor(Array *r_dest) {
-	memnew_placement(r_dest, Array);
-}
-
-void godot_icall_Array_At(Array *ptr, int32_t index, Variant *r_elem) {
-	if (index < 0 || index >= ptr->size()) {
-		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
-		*r_elem = Variant();
-		return;
-	}
-	*r_elem = ptr->operator[](index);
-}
-
-void godot_icall_Array_SetAt(Array *ptr, int32_t index, MonoObject *value) {
-	if (index < 0 || index >= ptr->size()) {
-		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
-		return;
-	}
-	ptr->operator[](index) = GDMonoMarshal::mono_object_to_variant(value);
-}
-
-int32_t godot_icall_Array_Count(Array *ptr) {
-	return ptr->size();
-}
-
-int32_t godot_icall_Array_Add(Array *ptr, MonoObject *item) {
-	ptr->append(GDMonoMarshal::mono_object_to_variant(item));
-	return ptr->size();
-}
-
-void godot_icall_Array_Clear(Array *ptr) {
-	ptr->clear();
-}
-
-MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item) {
-	return ptr->find(GDMonoMarshal::mono_object_to_variant(item)) != -1;
-}
-
-void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int32_t array_index) {
-	unsigned int count = ptr->size();
-
-	if (mono_array_length(array) < (array_index + count)) {
-		MonoException *exc = mono_get_exception_argument("", "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
-		GDMonoUtils::set_pending_exception(exc);
-		return;
-	}
-
-	for (unsigned int i = 0; i < count; i++) {
-		MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(ptr->operator[](i));
-		mono_array_setref(array, array_index, boxed);
-		array_index++;
-	}
-}
-
-void godot_icall_Array_Ctor_MonoArray(MonoArray *mono_array, Array *r_dest) {
-	memnew_placement(r_dest, Array);
-	unsigned int count = mono_array_length(mono_array);
-	r_dest->resize(count);
-	for (unsigned int i = 0; i < count; i++) {
-		MonoObject *item = mono_array_get(mono_array, MonoObject *, i);
-		godot_icall_Array_SetAt(r_dest, i, item);
-	}
-}
-
-void godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep, Array *r_dest) {
-	memnew_placement(r_dest, Array(ptr->duplicate(deep)));
-}
-
-void godot_icall_Array_Concatenate(Array *left, Array *right, Array *r_dest) {
-	int count = left->size() + right->size();
-	memnew_placement(r_dest, Array(left->duplicate(false)));
-	r_dest->resize(count);
-	for (unsigned int i = 0; i < (unsigned int)right->size(); i++) {
-		r_dest->operator[](i + left->size()) = right->operator[](i);
-	}
-}
-
-int32_t godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
-	return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
-}
-
-void godot_icall_Array_Insert(Array *ptr, int32_t index, MonoObject *item) {
-	if (index < 0 || index > ptr->size()) {
-		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
-		return;
-	}
-	ptr->insert(index, GDMonoMarshal::mono_object_to_variant(item));
-}
-
-MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item) {
-	int idx = ptr->find(GDMonoMarshal::mono_object_to_variant(item));
-	if (idx >= 0) {
-		ptr->remove_at(idx);
-		return true;
-	}
-	return false;
-}
-
-void godot_icall_Array_RemoveAt(Array *ptr, int32_t index) {
-	if (index < 0 || index >= ptr->size()) {
-		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
-		return;
-	}
-	ptr->remove_at(index);
-}
-
-int32_t godot_icall_Array_Resize(Array *ptr, int32_t new_size) {
-	return (int32_t)ptr->resize(new_size);
-}
-
-void godot_icall_Array_Shuffle(Array *ptr) {
-	ptr->shuffle();
-}
-
-MonoString *godot_icall_Array_ToString(Array *ptr) {
-	return GDMonoMarshal::mono_string_from_godot(Variant(*ptr).operator String());
-}
-
-void godot_icall_Dictionary_Ctor(Dictionary *r_dest) {
-	memnew_placement(r_dest, Dictionary);
-}
-
-void godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key, Variant *r_value) {
-	Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
-	if (ret == nullptr) {
-		MonoObject *exc = mono_object_new(mono_domain_get(), CACHED_CLASS(KeyNotFoundException)->get_mono_ptr());
-#ifdef DEBUG_ENABLED
-		CRASH_COND(!exc);
-#endif
-		GDMonoUtils::runtime_object_init(exc, CACHED_CLASS(KeyNotFoundException));
-		GDMonoUtils::set_pending_exception((MonoException *)exc);
-		*r_value = Variant();
-		return;
-	}
-	*r_value = *ret;
-}
-
-void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value) {
-	ptr->operator[](GDMonoMarshal::mono_object_to_variant(key)) = GDMonoMarshal::mono_object_to_variant(value);
-}
-
-void godot_icall_Dictionary_Keys(Dictionary *ptr, Array *r_dest) {
-	memnew_placement(r_dest, Array(ptr->keys()));
-}
-
-void godot_icall_Dictionary_Values(Dictionary *ptr, Array *r_dest) {
-	memnew_placement(r_dest, Array(ptr->values()));
-}
-
-int32_t godot_icall_Dictionary_Count(Dictionary *ptr) {
-	return ptr->size();
-}
-
-int32_t godot_icall_Dictionary_KeyValuePairs(Dictionary *ptr, Array *keys, Array *values) {
-	memnew_placement(keys, Array(ptr->keys()));
-	memnew_placement(values, Array(ptr->values()));
-	return ptr->size();
-}
-
-void godot_icall_Dictionary_KeyValuePairAt(Dictionary *ptr, int index, Variant *r_key, Variant *r_value) {
-	memnew_placement(r_key, Variant(ptr->get_key_at_index(index)));
-	memnew_placement(r_value, Variant(ptr->get_value_at_index(index)));
-}
-
-void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value) {
-	Variant varKey = GDMonoMarshal::mono_object_to_variant(key);
-	Variant *ret = ptr->getptr(varKey);
-	if (ret != nullptr) {
-		GDMonoUtils::set_pending_exception(mono_get_exception_argument("key", "An element with the same key already exists"));
-		return;
-	}
-	ptr->operator[](varKey) = GDMonoMarshal::mono_object_to_variant(value);
-}
-
-void godot_icall_Dictionary_Clear(Dictionary *ptr) {
-	ptr->clear();
-}
-
-MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value) {
-	// no dupes
-	Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
-	return ret != nullptr && *ret == GDMonoMarshal::mono_object_to_variant(value);
-}
-
-MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key) {
-	return ptr->has(GDMonoMarshal::mono_object_to_variant(key));
-}
-
-void godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep, Dictionary *r_dest) {
-	memnew_placement(r_dest, Dictionary(ptr->duplicate(deep)));
-}
-
-MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key) {
-	return ptr->erase(GDMonoMarshal::mono_object_to_variant(key));
-}
-
-MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value) {
-	Variant varKey = GDMonoMarshal::mono_object_to_variant(key);
-
-	// no dupes
-	Variant *ret = ptr->getptr(varKey);
-	if (ret != nullptr && *ret == GDMonoMarshal::mono_object_to_variant(value)) {
-		ptr->erase(varKey);
-		return true;
-	}
-
-	return false;
-}
-
-MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, Variant *value) {
-	Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
-	if (ret == nullptr) {
-		*value = Variant();
-		return false;
-	}
-	*value = *ret;
-	return true;
-}
-
-MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr) {
-	return GDMonoMarshal::mono_string_from_godot(Variant(*ptr).operator String());
-}
-
-void godot_register_collections_icalls() {
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", godot_icall_Array_Ctor);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", godot_icall_Array_Ctor_MonoArray);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_At", godot_icall_Array_At);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", godot_icall_Array_SetAt);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", godot_icall_Array_Count);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", godot_icall_Array_Add);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", godot_icall_Array_Clear);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", godot_icall_Array_Concatenate);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", godot_icall_Array_Contains);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", godot_icall_Array_CopyTo);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", godot_icall_Array_Duplicate);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", godot_icall_Array_IndexOf);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", godot_icall_Array_Insert);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", godot_icall_Array_Remove);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", godot_icall_Array_RemoveAt);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", godot_icall_Array_Resize);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", godot_icall_Array_Shuffle);
-	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", godot_icall_Array_ToString);
-
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", godot_icall_Dictionary_Ctor);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", godot_icall_Dictionary_GetValue);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", godot_icall_Dictionary_SetValue);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", godot_icall_Dictionary_Keys);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", godot_icall_Dictionary_Values);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", godot_icall_Dictionary_Count);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_KeyValuePairs", godot_icall_Dictionary_KeyValuePairs);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_KeyValuePairAt", godot_icall_Dictionary_KeyValuePairAt);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", godot_icall_Dictionary_Add);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", godot_icall_Dictionary_Clear);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", godot_icall_Dictionary_Contains);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", godot_icall_Dictionary_ContainsKey);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", godot_icall_Dictionary_Duplicate);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", godot_icall_Dictionary_RemoveKey);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", godot_icall_Dictionary_Remove);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", godot_icall_Dictionary_TryGetValue);
-	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ToString", godot_icall_Dictionary_ToString);
-}

+ 0 - 77
modules/mono/glue/node_path_glue.cpp

@@ -1,77 +0,0 @@
-/*************************************************************************/
-/*  node_path_glue.cpp                                                   */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "core/string/node_path.h"
-#include "core/string/ustring.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr) {
-	return (MonoBoolean)p_ptr->is_absolute();
-}
-
-int32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) {
-	return p_ptr->get_name_count();
-}
-
-MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx) {
-	return GDMonoMarshal::mono_string_from_godot(p_ptr->get_name(p_idx));
-}
-
-int32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) {
-	return p_ptr->get_subname_count();
-}
-
-MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx) {
-	return GDMonoMarshal::mono_string_from_godot(p_ptr->get_subname(p_idx));
-}
-
-MonoString *godot_icall_NodePath_get_concatenated_names(NodePath *p_ptr) {
-	return GDMonoMarshal::mono_string_from_godot(p_ptr->get_concatenated_names());
-}
-
-MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr) {
-	return GDMonoMarshal::mono_string_from_godot(p_ptr->get_concatenated_subnames());
-}
-
-void godot_icall_NodePath_get_as_property_path(NodePath *p_ptr, NodePath *r_dest) {
-	*r_dest = p_ptr->get_as_property_path();
-}
-
-void godot_register_node_path_icalls() {
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", godot_icall_NodePath_get_as_property_path);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_names", godot_icall_NodePath_get_concatenated_names);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", godot_icall_NodePath_get_concatenated_subnames);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", godot_icall_NodePath_get_name);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", godot_icall_NodePath_get_name_count);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", godot_icall_NodePath_get_subname);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", godot_icall_NodePath_get_subname_count);
-	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", godot_icall_NodePath_is_absolute);
-}

+ 209 - 9
modules/mono/glue/runtime_interop.cpp

@@ -56,6 +56,9 @@ extern "C" {
 #define GD_PINVOKE_EXPORT MAYBE_UNUSED
 #endif
 
+// For ArrayPrivate and DictionaryPrivate
+static_assert(sizeof(SafeRefCount) == sizeof(uint32_t));
+
 typedef Object *(*godotsharp_class_creation_func)();
 
 GD_PINVOKE_EXPORT MethodBind *godotsharp_method_bind_get_method(const StringName *p_classname, const char16_t *p_methodname) {
@@ -185,7 +188,7 @@ GD_PINVOKE_EXPORT void godotsharp_packed_string_array_add(PackedStringArray *r_d
 GD_PINVOKE_EXPORT void godotsharp_callable_new_with_delegate(void *p_delegate_handle, Callable *r_callable) {
 	// TODO: Use pooling for ManagedCallable instances.
 	CallableCustom *managed_callable = memnew(ManagedCallable(p_delegate_handle));
-	*r_callable = Callable(managed_callable);
+	memnew_placement(r_callable, Callable(managed_callable));
 }
 
 GD_PINVOKE_EXPORT bool godotsharp_callable_get_data_for_marshalling(const Callable *p_callable,
@@ -198,31 +201,31 @@ GD_PINVOKE_EXPORT bool godotsharp_callable_get_data_for_marshalling(const Callab
 			ManagedCallable *managed_callable = static_cast<ManagedCallable *>(custom);
 			*r_delegate_handle = managed_callable->get_delegate();
 			*r_object = nullptr;
-			*r_name = StringName();
+			memnew_placement(r_name, StringName());
 			return true;
 		} else if (compare_equal_func == SignalAwaiterCallable::compare_equal_func_ptr) {
 			SignalAwaiterCallable *signal_awaiter_callable = static_cast<SignalAwaiterCallable *>(custom);
 			*r_delegate_handle = nullptr;
 			*r_object = ObjectDB::get_instance(signal_awaiter_callable->get_object());
-			*r_name = signal_awaiter_callable->get_signal();
+			memnew_placement(r_name, StringName(signal_awaiter_callable->get_signal()));
 			return true;
 		} else if (compare_equal_func == EventSignalCallable::compare_equal_func_ptr) {
 			EventSignalCallable *event_signal_callable = static_cast<EventSignalCallable *>(custom);
 			*r_delegate_handle = nullptr;
 			*r_object = ObjectDB::get_instance(event_signal_callable->get_object());
-			*r_name = event_signal_callable->get_signal();
+			memnew_placement(r_name, StringName(event_signal_callable->get_signal()));
 			return true;
 		}
 
 		// Some other CallableCustom. We only support ManagedCallable.
 		*r_delegate_handle = nullptr;
 		*r_object = nullptr;
-		*r_name = StringName();
+		memnew_placement(r_name, StringName());
 		return false;
 	} else {
 		*r_delegate_handle = nullptr;
 		*r_object = ObjectDB::get_instance(p_callable->get_object_id());
-		*r_name = p_callable->get_method();
+		memnew_placement(r_name, StringName(p_callable->get_method()));
 		return true;
 	}
 }
@@ -235,7 +238,7 @@ GD_PINVOKE_EXPORT void godotsharp_method_bind_ptrcall(MethodBind *p_method_bind,
 	p_method_bind->ptrcall(p_instance, p_args, p_ret);
 }
 
-GD_PINVOKE_EXPORT godot_variant godotsharp_method_bind_call(MethodBind *p_method_bind, Object *p_instance, const godot_variant **p_args, const int p_arg_count, Callable::CallError *p_call_error) {
+GD_PINVOKE_EXPORT godot_variant godotsharp_method_bind_call(MethodBind *p_method_bind, Object *p_instance, const godot_variant **p_args, const int32_t p_arg_count, Callable::CallError *p_call_error) {
 	godot_variant ret;
 	memnew_placement(&ret, Variant());
 
@@ -575,6 +578,10 @@ GD_PINVOKE_EXPORT godot_packed_array godotsharp_variant_as_packed_color_array(co
 	return raw_dest;
 }
 
+GD_PINVOKE_EXPORT bool godotsharp_variant_equals(const godot_variant *p_a, const godot_variant *p_b) {
+	return *reinterpret_cast<const Variant *>(p_a) == *reinterpret_cast<const Variant *>(p_b);
+}
+
 // string.h
 
 GD_PINVOKE_EXPORT void godotsharp_string_new_with_utf16_chars(String *r_dest, const char16_t *p_contents) {
@@ -596,12 +603,24 @@ GD_PINVOKE_EXPORT void godotsharp_node_path_new_copy(NodePath *r_dest, const Nod
 
 // array.h
 
+GD_PINVOKE_EXPORT void godotsharp_array_new(Array *r_dest) {
+	memnew_placement(r_dest, Array);
+}
+
 GD_PINVOKE_EXPORT void godotsharp_array_new_copy(Array *r_dest, const Array *p_src) {
 	memnew_placement(r_dest, Array(*p_src));
 }
 
+GD_PINVOKE_EXPORT godot_variant *godotsharp_array_ptrw(godot_array *p_self) {
+	return reinterpret_cast<godot_variant *>(&reinterpret_cast<Array *>(p_self)->operator[](0));
+}
+
 // dictionary.h
 
+GD_PINVOKE_EXPORT void godotsharp_dictionary_new(Dictionary *r_dest) {
+	memnew_placement(r_dest, Dictionary);
+}
+
 GD_PINVOKE_EXPORT void godotsharp_dictionary_new_copy(Dictionary *r_dest, const Dictionary *p_src) {
 	memnew_placement(r_dest, Dictionary(*p_src));
 }
@@ -676,12 +695,156 @@ GD_PINVOKE_EXPORT void godotsharp_dictionary_destroy(Dictionary *p_self) {
 	p_self->~Dictionary();
 }
 
+// Array
+
+GD_PINVOKE_EXPORT int32_t godotsharp_array_add(Array *p_self, const Variant *p_item) {
+	p_self->append(*p_item);
+	return p_self->size();
+}
+
+GD_PINVOKE_EXPORT void godotsharp_array_duplicate(const Array *p_self, bool p_deep, Array *r_dest) {
+	memnew_placement(r_dest, Array(p_self->duplicate(p_deep)));
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_array_index_of(const Array *p_self, const Variant *p_item) {
+	return p_self->find(*p_item);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_array_insert(Array *p_self, int32_t p_index, const Variant *p_item) {
+	p_self->insert(p_index, *p_item);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_array_remove_at(Array *p_self, int32_t p_index) {
+	p_self->remove_at(p_index);
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_array_resize(Array *p_self, int32_t p_new_size) {
+	return (int32_t)p_self->resize(p_new_size);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_array_shuffle(Array *p_self) {
+	p_self->shuffle();
+}
+
+// Dictionary
+
+GD_PINVOKE_EXPORT bool godotsharp_dictionary_try_get_value(const Dictionary *p_self, const Variant *p_key, Variant *r_value) {
+	const Variant *ret = p_self->getptr(*p_key);
+	if (ret == nullptr) {
+		memnew_placement(r_value, Variant());
+		return false;
+	}
+	memnew_placement(r_value, Variant(*ret));
+	return true;
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_set_value(Dictionary *p_self, const Variant *p_key, const Variant *p_value) {
+	p_self->operator[](*p_key) = *p_value;
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_keys(const Dictionary *p_self, Array *r_dest) {
+	memnew_placement(r_dest, Array(p_self->keys()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_values(const Dictionary *p_self, Array *r_dest) {
+	memnew_placement(r_dest, Array(p_self->values()));
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_dictionary_count(const Dictionary *p_self) {
+	return p_self->size();
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_key_value_pair_at(const Dictionary *p_self, int32_t p_index, Variant *r_key, Variant *r_value) {
+	memnew_placement(r_key, Variant(p_self->get_key_at_index(p_index)));
+	memnew_placement(r_value, Variant(p_self->get_value_at_index(p_index)));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_add(Dictionary *p_self, const Variant *p_key, const Variant *p_value) {
+	p_self->operator[](*p_key) = *p_value;
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_clear(Dictionary *p_self) {
+	p_self->clear();
+}
+
+GD_PINVOKE_EXPORT bool godotsharp_dictionary_contains_key(const Dictionary *p_self, const Variant *p_key) {
+	return p_self->has(*p_key);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_dictionary_duplicate(const Dictionary *p_self, bool p_deep, Dictionary *r_dest) {
+	memnew_placement(r_dest, Dictionary(p_self->duplicate(p_deep)));
+}
+
+GD_PINVOKE_EXPORT bool godotsharp_dictionary_remove_key(Dictionary *p_self, const Variant *p_key) {
+	return p_self->erase(*p_key);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_string_md5_buffer(const String *p_self, PackedByteArray *r_md5_buffer) {
+	memnew_placement(r_md5_buffer, PackedByteArray(p_self->md5_buffer()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_string_md5_text(const String *p_self, String *r_md5_text) {
+	memnew_placement(r_md5_text, String(p_self->md5_text()));
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_string_rfind(const String *p_self, const String *p_what, int32_t p_from) {
+	return p_self->rfind(*p_what, p_from);
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_string_rfindn(const String *p_self, const String *p_what, int32_t p_from) {
+	return p_self->rfindn(*p_what, p_from);
+}
+
+GD_PINVOKE_EXPORT void godotsharp_string_sha256_buffer(const String *p_self, PackedByteArray *r_sha256_buffer) {
+	memnew_placement(r_sha256_buffer, PackedByteArray(p_self->sha256_buffer()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_string_sha256_text(const String *p_self, String *r_sha256_text) {
+	memnew_placement(r_sha256_text, String(p_self->sha256_text()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_string_simplify_path(const String *p_self, String *r_simplified_path) {
+	memnew_placement(r_simplified_path, String(p_self->simplify_path()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_node_path_get_as_property_path(const NodePath *p_ptr, NodePath *r_dest) {
+	memnew_placement(r_dest, NodePath(p_ptr->get_as_property_path()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_node_path_get_concatenated_names(const NodePath *p_self, String *r_subnames) {
+	memnew_placement(r_subnames, String(p_self->get_concatenated_names()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_node_path_get_concatenated_subnames(const NodePath *p_self, String *r_subnames) {
+	memnew_placement(r_subnames, String(p_self->get_concatenated_subnames()));
+}
+
+GD_PINVOKE_EXPORT void godotsharp_node_path_get_name(const NodePath *p_self, uint32_t p_idx, String *r_name) {
+	memnew_placement(r_name, String(p_self->get_name(p_idx)));
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_node_path_get_name_count(const NodePath *p_self) {
+	return p_self->get_name_count();
+}
+
+GD_PINVOKE_EXPORT void godotsharp_node_path_get_subname(const NodePath *p_self, uint32_t p_idx, String *r_subname) {
+	memnew_placement(r_subname, String(p_self->get_subname(p_idx)));
+}
+
+GD_PINVOKE_EXPORT int32_t godotsharp_node_path_get_subname_count(const NodePath *p_self) {
+	return p_self->get_subname_count();
+}
+
+GD_PINVOKE_EXPORT bool godotsharp_node_path_is_absolute(const NodePath *p_self) {
+	return p_self->is_absolute();
+}
+
 #ifdef __cplusplus
 }
 #endif
 
 // We need this to prevent the functions from being stripped.
-void *godotsharp_pinvoke_funcs[101] = {
+void *godotsharp_pinvoke_funcs[138] = {
 	(void *)godotsharp_method_bind_get_method,
 	(void *)godotsharp_get_class_constructor,
 	(void *)godotsharp_invoke_class_constructor,
@@ -761,10 +924,14 @@ void *godotsharp_pinvoke_funcs[101] = {
 	(void *)godotsharp_variant_as_packed_vector2_array,
 	(void *)godotsharp_variant_as_packed_vector3_array,
 	(void *)godotsharp_variant_as_packed_color_array,
+	(void *)godotsharp_variant_equals,
 	(void *)godotsharp_string_new_with_utf16_chars,
 	(void *)godotsharp_string_name_new_copy,
 	(void *)godotsharp_node_path_new_copy,
+	(void *)godotsharp_array_new,
 	(void *)godotsharp_array_new_copy,
+	(void *)godotsharp_array_ptrw,
+	(void *)godotsharp_dictionary_new,
 	(void *)godotsharp_dictionary_new_copy,
 	(void *)godotsharp_packed_byte_array_destroy,
 	(void *)godotsharp_packed_int32_array_destroy,
@@ -782,5 +949,38 @@ void *godotsharp_pinvoke_funcs[101] = {
 	(void *)godotsharp_signal_destroy,
 	(void *)godotsharp_callable_destroy,
 	(void *)godotsharp_array_destroy,
-	(void *)godotsharp_dictionary_destroy
+	(void *)godotsharp_dictionary_destroy,
+	(void *)godotsharp_array_add,
+	(void *)godotsharp_array_duplicate,
+	(void *)godotsharp_array_index_of,
+	(void *)godotsharp_array_insert,
+	(void *)godotsharp_array_remove_at,
+	(void *)godotsharp_array_resize,
+	(void *)godotsharp_array_shuffle,
+	(void *)godotsharp_dictionary_try_get_value,
+	(void *)godotsharp_dictionary_set_value,
+	(void *)godotsharp_dictionary_keys,
+	(void *)godotsharp_dictionary_values,
+	(void *)godotsharp_dictionary_count,
+	(void *)godotsharp_dictionary_key_value_pair_at,
+	(void *)godotsharp_dictionary_add,
+	(void *)godotsharp_dictionary_clear,
+	(void *)godotsharp_dictionary_contains_key,
+	(void *)godotsharp_dictionary_duplicate,
+	(void *)godotsharp_dictionary_remove_key,
+	(void *)godotsharp_string_md5_buffer,
+	(void *)godotsharp_string_md5_text,
+	(void *)godotsharp_string_rfind,
+	(void *)godotsharp_string_rfindn,
+	(void *)godotsharp_string_sha256_buffer,
+	(void *)godotsharp_string_sha256_text,
+	(void *)godotsharp_string_simplify_path,
+	(void *)godotsharp_node_path_get_as_property_path,
+	(void *)godotsharp_node_path_get_concatenated_names,
+	(void *)godotsharp_node_path_get_concatenated_subnames,
+	(void *)godotsharp_node_path_get_name,
+	(void *)godotsharp_node_path_get_name_count,
+	(void *)godotsharp_node_path_get_subname,
+	(void *)godotsharp_node_path_get_subname_count,
+	(void *)godotsharp_node_path_is_absolute
 };

+ 0 - 81
modules/mono/glue/string_glue.cpp

@@ -1,81 +0,0 @@
-/*************************************************************************/
-/*  string_glue.cpp                                                      */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "core/string/ustring.h"
-#include "core/templates/vector.h"
-#include "core/variant/variant.h"
-
-#include "../mono_gd/gd_mono_marshal.h"
-
-MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) {
-	Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer();
-	// TODO Check possible Array/Vector<uint8_t> problem?
-	return GDMonoMarshal::Array_to_mono_array(Variant(ret));
-}
-
-MonoString *godot_icall_String_md5_text(MonoString *p_str) {
-	String ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_text();
-	return GDMonoMarshal::mono_string_from_godot(ret);
-}
-
-int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from) {
-	String what = GDMonoMarshal::mono_string_to_godot(p_what);
-	return GDMonoMarshal::mono_string_to_godot(p_str).rfind(what, p_from);
-}
-
-int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from) {
-	String what = GDMonoMarshal::mono_string_to_godot(p_what);
-	return GDMonoMarshal::mono_string_to_godot(p_str).rfindn(what, p_from);
-}
-
-MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str) {
-	Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_buffer();
-	return GDMonoMarshal::Array_to_mono_array(Variant(ret));
-}
-
-MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
-	String ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_text();
-	return GDMonoMarshal::mono_string_from_godot(ret);
-}
-
-MonoString *godot_icall_String_simplify_path(MonoString *p_str) {
-	String ret = GDMonoMarshal::mono_string_to_godot(p_str).simplify_path();
-	return GDMonoMarshal::mono_string_from_godot(ret);
-}
-
-void godot_register_string_icalls() {
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", godot_icall_String_md5_buffer);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", godot_icall_String_md5_text);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", godot_icall_String_rfind);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", godot_icall_String_rfindn);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", godot_icall_String_sha256_buffer);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", godot_icall_String_sha256_text);
-	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_simplify_path", godot_icall_String_simplify_path);
-}

+ 0 - 7
modules/mono/mono_gd/gd_mono.cpp

@@ -442,22 +442,15 @@ bool GDMono::_are_api_assemblies_out_of_sync() {
 	return out_of_sync;
 }
 
-void godot_register_collections_icalls();
 void godot_register_gd_icalls();
-void godot_register_node_path_icalls();
 void godot_register_object_icalls();
-void godot_register_rid_icalls();
-void godot_register_string_icalls();
 void godot_register_scene_tree_icalls();
 void godot_register_placeholder_icalls();
 
 void GDMono::_register_internal_calls() {
 	// Registers internal calls that were not generated.
-	godot_register_collections_icalls();
 	godot_register_gd_icalls();
-	godot_register_node_path_icalls();
 	godot_register_object_icalls();
-	godot_register_string_icalls();
 	godot_register_scene_tree_icalls();
 	godot_register_placeholder_icalls();
 }