翻译 from peter1745的《mono-guide》
强烈建议阅读Mono官方文档
配置运行时环境
现在我们已经构建了Mono并获取了所有必要的文件,希望也正确地设置了项目,是时候开始编写代码了!我们首先要做的是初始化Mono运行时环境。
为了正确地初始化Mono,我们需要首先包含 mono/jit/jit.h
和 mono/metadata/assembly.h
。一旦完成这一步,我们需要告诉Mono.NET
库的位置。我们将要调用的函数是 mono_set_assemblies_path
。请注意,传递给该函数的路径必须是绝对路径(例如 D:\dev\Engine\mono\lib
)或相对于当前工作目录的路径(例如 mono/lib
)。
在我的情况下,它看起来像这样:
void InitMono()
{
mono_set_assemblies_path("mono/lib");
}
如果您没有提供 Mono 的此路径,您将在控制台中看到一条错误消息,它看起来像这样:
如果您没有提供这个路径,但有一个指向正确文件夹的 MONO_PATH
环境变量,Mono 将尝试使用该路径来定位 mscorlib.dll
。
一旦我们告诉Mono在哪里找到mscorlib,我们就可以真正启动运行时环境了。我们必须调用 mono_jit_init
以启动运行时环境,但您可能会注意到实际上还有另一个函数,名字相似:mono_jit_init_version
,那么它们有什么区别呢?嗯,区别在于我们使用的运行时版本。通过使用第一个函数(mono_jit_init
),我们告诉Mono使用第一个加载的程序集引用的运行时版本,这意味着它将自动检测它。如果我们使用第二个函数 mono_jit_init_version
,我们可以指定我们想要使用的确切运行时版本。
根据我的实验,使用哪个函数并没有太大影响,一般来说,让Mono自动选择运行时版本更安全。因此,在本指南中,我们将使用 mono_jit_init
。在调用此函数时,务必给它传递一个字符串,这个字符串本质上代表runtime的名称。
在调用此函数时,我们会得到一个 MonoDomain
指针,重要的是我们要存储这个指针,因为稍后我们必须手动清理它。有趣的是,Mono 实际上也在内部存储了这个指针,根据Mono开发人员的说法,我们实际上不需要跟踪这个指针,但事实就是这样,所以确保将它存储在某个地方。
void InitMono()
{
mono_set_assemblies_path("mono/lib");
MonoDomain* rootDomain = mono_jit_init("MyScriptRuntime");
if (rootDomain == nullptr)
{
// Maybe log some error here
return;
}
// 存放这个rootDomain
s_RootDomain = rootDomain;
}
这是初始化 Mono runtime 的基础知识。随着我们继续进一步开发脚本引擎,初始化过程可能会变得更加复杂,但我们将在需要时涵盖必要的部分。
现在初始化工作还没有完成,在加载C#程序集并开始运行代码之前,我们需要创建一个应用程序域(App Domain)。
创建一个应用程序域(App Domain)
创建一个应用程序域(App Domain)在Mono中非常简单,我们只需要调用 mono_domain_create_appdomain
并为我们的应用程序域命名。记得将该函数返回的 MonoDomain
指针存储在某个地方,我们稍后会用到它。将来这个过程可能会变得稍微复杂一些,但目前我们只需修改我们的初始化函数如下:
void InitMono()
{
mono_set_assemblies_path("mono/lib");
MonoDomain* rootDomain = mono_jit_init("MyScriptRuntime");
if (rootDomain == nullptr)
{
// Maybe log some error here
return;
}
// Store the root domain pointer
s_RootDomain = rootDomain;
// Create an App Domain
s_AppDomain = mono_domain_create_appdomain("MyAppDomain", nullptr);
mono_domain_set(s_AppDomain, true);
}
你可能想知道 mono_domain_create_appdomain
的第二个参数是什么,实际上它允许我们传递一个配置文件的路径。由于我们不需要这个,我们可以简单地传递 nullptr。
一旦我们有了 MonoDomain 指针,我们需要将我们的新应用程序域设置为当前应用程序域,我们可以通过调用 mono_domain_set
并传递我们的域来实现这一点。第二个参数简单地指示我们是否要强制将我们的域设置为当前域。实际上,我们可能可以传递 false
,因为该参数的作用只是在即使正在卸载 App Domain
的情况下强制设置它,但我们将继续传递 true。
现在我们已经创建了我们的应用程序域,我们终于可以着手运行 C# 代码了!我们现在只需要加载一个 C# 程序集,这将在下一节中介绍。