Unity源码中C#到C++的绑定是通过一个描述C#和C++代码的txt文件(如UnityEngineGameObject.txt)来生成的。
这类文件放在Runtime\Export和Editor\Mono目录下,Unity源码会根据它们生成一个.cs和一个.cpp文件。.cs文件提供了C#层的接口,.cpp文件通过mono_add_internal_call实现了C#到C++的绑定。
Unity采用Embedding Mono的方式实现C#到C++的调用,Embedding Mono参考http://www.mono-project.com/docs/advanced/embedding/。
其C#层的对象都继承于UnityEngine.Object,Object中有一个很重要的成员变量m_UnityRuntimeReferenceData:
Unity通过这里的cachedPtr存储C++层与之关联的对象的内存地址。
当C#层通过Mono调用C++方法时传入对象的this引用,C++方法将获得一个MonoObject的对象指针(MonoObject*,Unity typedef MonoObject为ScriptingObject),这个对象指针指向的内存其实就是C#对象的内存,其内存布局如图:
如上图,Mono中每个C#对象的内存布局都以MonoObject开始,而Unity中每个C#对象的内存布局是紧接在MonoObject后会有一个ReferenceData。因此Unity C++层定义了一个UnityEngineObjectMemoryLayout与C#层ReferenceData相对应:
MonoObject的定义:
https://github.com/mono/mono/blob/master/mono/metadata/object.h
http://docs.go-mono.com/index.aspx?link=xhtml%3Adeploy%2Fmono-api-object.html
Unity C++层通过将C#层的对象内存地址+8bytes来取得ReferenceData结构并解析为UnityEngineObjectMemoryLayout,同时将C++层与C#绑定的对象使用cachedPtr进行存取。