前置博文:
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;
};
以上只是其中一种管理方式的基本示例。