-1

mono_class_from_name_case 返回 nullptr,我发现无法获得更多信息,而且 mono 文档非常基础。我的问题是,我想我遗漏了一些东西,是否有一种方法可以将两个程序集“链接”在一起?这甚至需要吗?为什么该类出现在元数据中但无法通过 get 类访问?
我通过元数据接口获取名称和命名空间,它们是有效的字符串。dll 编译时没有任何警告/错误。在组件的打开和元数据访问之间没有其他操作。该代码首先针对 base.dll 执行,然后针对 content.dll 执行。两者都在同一个域中,但不同的程序集和图像。

我注意到的事情:
删除 Slime 中的基类“修复”它。<- 可能缺少对 base.dll 的引用?
当基础不是抽象的/没有任何虚拟方法时,它仍然不起作用
从 mono_class_from_name_case 更改为 mono_class_from_name 具有相同的行为。

C++ 代码:

    //metadata.getRaw returns a MonoImage* loaded with mono_domain_assembly_open & mono_assembly_get_image, the base dll is loaded first
    const MonoTableInfo* table_info = mono_image_get_table_info(metadata.GetRaw(), MONO_TABLE_TYPEDEF);
    int rows = mono_table_info_get_rows(table_info);


    for (int i = 0; i < rows; i++)
    {
        MonoClass* _class = nullptr;
        uint32_t cols[MONO_TYPEDEF_SIZE];
        mono_metadata_decode_row(table_info, i, cols, MONO_TYPEDEF_SIZE);
        const char* name = mono_metadata_string_heap(metadata.GetRaw(), cols[MONO_TYPEDEF_NAME]);
        const char* name_space = mono_metadata_string_heap(metadata.GetRaw(), cols[MONO_TYPEDEF_NAMESPACE]);

        //this returns nullptr for a valid class, i think the base dll is not loaded
        _class = mono_class_from_name_case(metadata.GetRaw(), name_space, name);

        //this does happen...
        if (_class == nullptr) {
            continue;
        }

    }

涉及的两个 DLL:

Base.dll

csc.exe -target:library -nologo -optimize+ -debug- -out:Base.dll Item.cs
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Base
{

    public abstract class Item
    {
        public Item()
        {

        }

        public abstract bool init();
        public abstract void release();

    }

}

内容.dll

csc.exe -target:library -nologo -optimize+ -debug- -reference:Base.dll -out:Content.dll Slime.cs
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Content{
    
    public class Slime : Base.Item
    {
        public Slime()
        {

        }

        public override bool init()
        {
            return true;
        }
        public override void release()
        {

        }


    }

    
}
4

1 回答 1

0

我发现“错误”mono_assembly_load 和 mono_domain_assembly_open 之间存在差异。使用 mono_assembly_load 它可以工作。

于 2021-04-28T16:19:41.993 回答