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));
//......
}