zhouqijie

C#接口:

//***Program.cs***
public class GameObject
{
    //句柄
    private IntPtr native_handle = (IntPtr)0;
    //GetGameObject方法
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern static GameObject[] GetGameObjects();

    //属性实现方法1(Internal):直接将C#句柄作为方法参数传入到C++的类对象指针。
    public int ID
    {
        get
        {
            return get_id_Internal(this.native_handle);
        }
    }
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern static int get_id_Internal(IntPtr native_handle);

    //属性实现方法2:在C/C++代码中先通过mono_field_get_value方法获取IntPtr句柄,然后转换成C++类对象指针。
    //(属性在C++端的名称为"get_属性名")
    public int Tag
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        get;
    }
}
//补充:1.定义的外部接口必须由static修饰.
//补充:2.用static修饰就不能使用virtual/override修饰。

C++类定义:

//***GameObject.h***
class GameObject
{
public:
	int id;
	int tag;
};

C++实现:

//***main.cpp***

//全局变量
vector<GameObject *> GameObjects;

//MonoClass:GameObject
MonoClass* GameObject_class;//GameObject的Mono类
MonoClassField* native_handle_field;//GameObject的Mono类的Mono字段:句柄

//ID属性的对应实现
int MonoCSharp_GameObject_get_id_Internal(const GameObject* GameObject)
{
	return GameObject->id;
}
//Tag属性的对应实现
int MonoCSharp_GameObject_get_tag(MonoObject* this_ptr)
{
	GameObject* gameObject;
	mono_field_get_value(this_ptr, native_handle_field, reinterpret_cast<void*>(&gameObject));
	return gameObject->tag;
}
//GetGameObjects方法的对应实现
MonoArray* MonoCSharp_GameObject_GetGameObjects()
{
	MonoArray* array = mono_array_new(domain, GameObject_class, num_GameObjects);

	for (uint32_t i = 0; i < num_GameObjects; ++i)
	{
		MonoObject* obj = mono_object_new(domain, GameObject_class);
		mono_runtime_object_init(obj);
		void* native_handle_value = &gameObjects[i];
		mono_field_set_value(obj, native_handle_field, &native_handle_value);
		mono_array_set(array, MonoObject*, i, obj);
	}

	return array;
}

int main()
{
    //......
    //赋值MonoClass和MonoClassField
    GameObject_class = mono_class_from_name(image, "MonoCSharp", "GameObject");
	native_handle_field = mono_class_get_field_from_name(GameObject_class, "native_handle");
    //将C#中的接口和C/C++中的具体实现关联起来。
	mono_add_internal_call("MonoCSharp.GameObject::get_id_Internal", reinterpret_cast<void*>(MonoCSharp_GameObject_get_id_Internal));
	mono_add_internal_call("MonoCSharp.GameObject::get_Tag", reinterpret_cast<void*>(MonoCSharp_GameObject_get_tag));
	mono_add_internal_call("MonoCSharp.GameObject::GetGameObjects", reinterpret_cast<void*>(MonoCSharp_GameObject_GetGameObjects));
    //......
}