【问题标题】:mono_class_from_name_case returns nullptrmono_class_from_name_case 返回 nullptr
【发布时间】:2021-07-21 01:24:23
【问题描述】:

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

我注意到的事情:
删除 Slime 中的基类“修复”它。 当基础不抽象/没有任何虚拟方法时,它仍然不起作用
从 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()
        {

        }


    }

    
}

【问题讨论】:

  • C++ 不是 C。标签已编辑。

标签: c# c++ mono mono-embedding


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 2021-05-22
    • 1970-01-01
    • 2023-04-03
    • 2015-08-27
    • 2023-04-10
    • 2019-01-28
    • 2013-05-11
    相关资源
    最近更新 更多