我有一个问题已经处理了一周,你不会相信我已经检查了所有可能的东西,但它仍然不能正常工作。现在我正在为我的游戏引擎编写脚本系统,我需要动态重新编译/重新加载包含我的库和脚本的dll文件。为此,我执行以下操作:
这是我的Mono初始化代码:
- 初始化Mono(我得到了一个已为我创建的应用程序域(MonoDomain*))
- 打开程序集文件(dll)
- 从该程序集获取映像
- 使用mono(我加载内部调用,创建C#对象,调用函数等)。
- 创建新的域
- 上传映像
- 将映像连接到对象程序集(从而使映像状态为OK)
- 然后才描述最后一个域的资源
这是我的Mono初始化代码:
mono_set_dirs(".", ".");
// 0. Load first domain, init mono + appdomain + load assembly.
const char* domainName = "ForceCS";
const char* assemblyName = "ForceCS.dll";
pMonoDomain = mono_jit_init(domainName);
if (pMonoDomain) {
pMonoAssembly = mono_domain_assembly_open(pMonoDomain, assemblyName);
if (pMonoAssembly) {
pMonoImage = mono_assembly_get_image(pMonoAssembly);
if (pMonoImage) {
AddInternalFunctionsAndScriptClasses(); // mono_add_internal_call ...
}
}
}
然后我会使用我的动态链接库做一些事情,比如创建对象或调用方法,就像我之前说的那样。然后尝试重新加载ForceCS.dll。
// 1. Load new domain (Works fine).
char* newDomainName = "ForceCS";
MonoDomain* newDomain = mono_domain_create_appdomain(newDomainName, NULL);
if (!mono_domain_set(newDomain, false)) {
// Cannot set domain!
}
// 2. Load image. (Works fine)
const char* dllFile = "C:\\Force\\Editor\\ForceCS.dll";
MonoImageOpenStatus status;
MonoImage* newImage = mono_image_open(dllFile, &status); ** Problem here: Shows the same address as before and that means that Mono use same .dll.**
// 3. Load new assembly. (Works fine).
MonoAssembly* assembly = mono_assembly_load_from(newImage, mono_image_get_name(newImage), &status);
if (status != MonoImageOpenStatus::MONO_IMAGE_OK) {
///Cannot load assembly!
}
assembly = mono_assembly_open(dllFile, &status);
newImage = mono_assembly_get_image(assembly);
if (newImage) {
AddInternalFunctionsAndScriptClasses();
}
// 4. Inload old domain.
MonoDomain* domainToUnload = pMonoDomain == nullptr ? mono_domain_get() : pMonoDomain;
if (domainToUnload && domainToUnload != mono_get_root_domain()) {
mono_domain_unload(domainToUnload);
mono_gc_collect(mono_gc_max_generation());
mono_domain_finalize(domainToUnload, 2000);
mono_gc_collect(mono_gc_max_generation());
pMonoDomain = newDomain;
pMonoImage = newImage;
pMonoAssembly = assembly;
}
最终问题是图像始终保持不变,只有在我使用不同的名称(例如ForceCS1.dll)加载此程序集时才起作用,但这不是我想要的。请解释一下:
- 何时需要关闭/释放域、程序集、图像。
- 程序集-图像之间的关联是什么。
- 如何重新加载我的.dll程序集。
我将非常感谢每一个答案。