前置博文:

C# 自带 GC,在独立使用时无需额外处理;cpp 一侧内存管理技术则较多,如智能指针等。

在混合编程场景下,c# 层作为脚本运行时,cpp 层负责书写核心代码,内存消耗接近两倍,但这不是本文的重点。本文阐述两者之间的内存关系与混合管理方式。方案的核心是:cpp 层通过 handle 指向 c# 对象,c# 端维护 handle 与实际对象之间的引用关系。下面通过具体案例说明这种方式。

C# 层

public class GameObject : object
{
    private long _native_handle;//cpp ptr for
};


//提供全局c# 对象 c++引用
static class CppReferenceInternal
{
    public static Dictionary<int, object> global_cpp_ref = new Dictionary<int, object>();
    public static void Retain(object obj)
    {
        int hash = obj.GetHashCode();
        if (global_cpp_ref.ContainsKey(hash) == false)
        {
            global_cpp_ref.Add(hash, obj);
        }
    }
    public static void Release(object obj)
    {
        int hash = obj.GetHashCode();
        if (global_cpp_ref.ContainsKey(hash))
        {
            global_cpp_ref.Remove(hash);
        }
    }
}

C++ 层

class GameObject
	{
	public:
		static GameObject*Create()
		{
			GameObject *ret = new GameObject();
			return ret;
		};
		GameObject()
		{
			AllocMonoObject();
		}
		~GameObject()
		{
			FreeMonoObject();
		}
	private:
		bool FreeMonoObject()
		{
			MonoObjectRelease(mono_object_handle);
			mono_object_handle = nullptr;
			return true;
		}
		bool AllocMonoObject()
		{
			MonoClass *cls = mono_class_from_name(mono_assembly_get_image(mono_stick_engine_dll), "", "GameObject");
			mono_object_handle = mono_object_new(vm, cls);
			//call default ctor
			mono_runtime_object_init(mono_object_handle);

			MonoObjectRetatin(mono_object_handle);
			return true;
		}
	private:
		MonoObject * mono_object_handle = nullptr;
	};

以上只是其中一种管理方式的基本示例。