Mono 和游戏

本文探讨了Unity引擎中C#与C++的交互原理,重点解析了Mono框架的作用及其实现细节,包括如何利用Mono进行跨语言调用,以及在实际项目中的应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       Unity真的挺火的,我自己使用Unity不到两年时间吧,对这个引擎的理解也就仅限于使用层面,并不精通,我一直觉得想要学好什么东西,并不是要看文档看书,看视频什么的,而是要做点东西出来,我做与Unity引擎相关的工作,所以我想模仿Unity做一个引擎,目标是订的有些太玄,但是一步一个小目标嘛,慢慢来吧。

         是Unity第一次把Mono这个东西呈现到我的面前的,所以其实首先我想要做的是研究下Mono这个东西,对Mono这个框架的介绍我就不说了,网上虽然不多,不过我能说出来的也不比网上多!

        我们直接来看怎么用吧,先到Mono的GitHub上把代码下载下来,然后编译,在Mono目录中有一个叫msvc的文件夹,这里面就是visual studio工程,本人比较low只会在windows下写代码,至于怎么到linux下或者mac下编译我也搞不懂,O(∩_∩)O哈哈~。

        我们打开ILSpy,看一下UnityEngine这个dll,看一下GameObject这个类,我们会看到很多这样的属性标签:[MethodImpl(MethodImplOptions.InternalCall)],这个属性标签是什么意思呢?MSDN的解释是 “该调用为内部调用,也就是说它调用了在公共语言运行时中实现的方法”。说的是这个函数不是在C#中实现,而是在公共语言运行时里面实现的,放到Mono这边,他就是在Mono运行时或者是链接了Mono运行时的应用程序中实现的,Unity里就是在Unity的C++代码中实现的。

       从mono源码中我们找到了mono_add_internal_call这个函数,看起来和前面那个属性标签应该是对应的,这个函数有两个参数,const char *name 和  const void* method,从字面上理解就应该是函数的名字和指向函数的指针,确实是这样的,name是C#中的函数名,method是C++中的函数地址,这样通过这个函数就能够将C#中的函数和C++中的函数关联起来了,那么这个函数名该怎么给呢?他是以这样 namespace.class::function 的形式给的,如果在C#中定义的是静态函数,那么在C++中函数的参数和C#中一致,如果在C#中定义的是成员函数,C++中函数参数的第一个参数就是这个成员函数所在类的this引用。

       说到这,其实C#调用Mono C++中函数其实就那么回事,但是刚才我已经编译好了Mono的dll和一堆lib,那Mono我到底该怎么用呢?先把该链接的文件,该包含的目录,该引用的文件都配好写好,接下来初始化Mono环境,按照下面这个顺序

mono_set_assemblies_path (const char* path); // 设置运行时需要的库目录,这里面包含.net运行时需要的一些dll 如mscorlib等,注意要和你编译自己代码的.netframework版本一致


mono_config_parse(const char *filename); // 设置config ,可以给NULL

mono_jit_init (const char *file); // 填写自己编译的dll文件的路径

mono_thread_set_main(mono_thread_current());

mono_domain_assembly_open  (MonoDomain *domain, const char *name);// mono_jit_init 会返回一个DoMain就是这个函数的第一个参数,name给自己编译的dll文件路径。

mono_domain_set(MonoDomain *domain, mono_bool force); // 第一个domain ,第二个给true

mono_assembly_get_image  (MonoAssembly *assembly)// mono_domain_assembly_open  会返回一个MonoAssembly,传给这个函数,这个函数返回值是MonoImage*

        接下来就可以注册自己在C#中写的函数了。只要初始化没有问题了,其他的就可以自己发挥了,另外在Mono里面一旦出现错误就会立即exit,很让人苦恼,很多时候程序崩溃了根本搞不清楚为什么,但是在崩溃之前都会调用一些输出日志的函数,比如下面这三个,可以在这三个里面下上断点,一旦调用就可以知道什么时候为什么崩溃了。

mono_trace_set_log_handler(MonoLogCallback, nullptr);
mono_trace_set_print_handler(MonoPrintCallback);
mono_trace_set_printerr_handler(MonoPrintCallback);

        我很多时候对很多事情都抱着不求甚解的态度,其实这样不太好,尤其是面试的时候,面试官特别喜欢刁难人,所以有些事情还真得搞透彻点,用得对和用得恰到好处还是有区别的,所以希望大家不吝赐教,贴一下我的GitHub地址 https://github.com/panqingyun/E3D-Engine 这个里面就用到了Mono,上面说的比较宽泛,不够具体,详细代码可以看一下这里 https://github.com/panqingyun/E3D-Engine/tree/master/Engine/EngineCore/src/Mono,有错误欢迎批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值