как использовать MonoType в контексте оценки сигнатур методов

#mono #embedding

#mono #встраивание

Вопрос:

Я хочу иметь возможность вызывать методы в классах CLR из C . В частности, некоторые классы могут содержать перегруженные методы, поэтому мне нужно искать методы класса на основе как имени метода, так и сигнатуры параметра.

У меня есть такая функция:

 MonoMethod* find_method (
    MonoDomain* domain, 
    MonoClass* type, 
    const char* name, 
    int nargs,
    MonoClass** types)    
 

Я перебираю члены класса, находя соответствующий элемент по имени. Затем мне нужно проверить параметры метода и посмотреть, соответствуют ли они списку, требуемому в параметре types этой функции.

mono_signature_get_params() затем используется для перебора параметров для каждого метода с соответствующим именем.

Вопросы: Как я могу сделать следующее:

  1. доступ к полям структуры MonoClass и MonoType
    • попытка доступа к полям в этих структурах приводит к ошибке, так как неполные структуры
  2. сравните список параметров метода с другим списком, предоставленным в качестве входных данных для функции
    • невозможно сравнить по перечислению, поскольку невозможно получить доступ к полю перечисления (см. Выше)
  3. получить MonoClass* константы для основных типов и т.д. int32_class, int64_class
    • хотите иметь возможность легко составлять массив сигнатур, используя константы класса примитивного типа

Вот 2 вспомогательные функции, которые не компилируются, поскольку при доступе к полям в MonoType * или MonoClass * компилятор жалуется, указывая, что две структуры являются неполными:

 //
//  Detetermine whether classes A and B are equivalent
//
static bool IsEquivalent (MonoType* typeA, MonoType* typeB)
{
    MonoTypeEnum Ta = typeA->type; 
    MonoTypeEnum Tb = typeB->type;

    // if basic type not a match, can punt
    if (Ta != Tb)
        return false;

    // if simple type, nothing further to check 
    if (Ta < MONO_TYPE_PTR)
        return true;

    // check class
    if (Ta == MONO_TYPE_CLASS)
        return typeA->data.klass = typeB->data.klass;
    else
        return typeA->data.klass = typeB->data.klass;        
}


//
//  Determine whether parameters in signature match incoming parameters
//
static bool types_match (
    MonoMethodSignature* sig, 
    MonoClass** types, 
    int nargs)
{
    void* iter = NULL;
    MonoType* type = NULL;

    int i = 0;
    while (type = mono_signature_get_params (sig, amp;iter))
    {
        if (!IsEquivalent (type, types[i  ]->this_arg))
            return false;
    }

    return true;
}
 

Комментарии:

1. Хорошо, эта проблема, похоже, связана с тем, что mono предоставляет для общественного потребления по сравнению с внутренним. Включение внутренних заголовков решает проблему компиляции.

2. Похоже, мне нужно обсудить это с сообществом разработчиков mono, поскольку обычное использование не позволяет взаимодействовать с этими структурами данных.

Ответ №1:

Вы не должны включать частные заголовки mono: ваше приложение сломается, когда мы внесем изменения во внутренние компоненты.

Чтобы получить доступ к значению перечисления типа из MonoType *, вам необходимо вызвать функцию mono_type_get_type () (из метаданных / metadata.h). Для MONO_TYPE_CLASS и MONO_TYPE_VALUETYPE вы можете получить доступ к значению MonoClass * с помощью mono_type_get_class () .

Для сравнения двух сигнатур на равенство вы можете использовать mono_metadata_signature_equal(): обратите внимание, что использование MonoClass* для представления типа аргумента в корне неверно, поскольку это не может представлять, например, аргумент, переданный по ссылке.

Если вам нужно сопоставить по назначению, вы можете использовать mono_class_is_assignable_from() , но учтите, что вам нужно будет иметь дело с аргументами byref, решить, хотите ли вы разрешить перечисляемым типам автоматическое преобразование в их базовый целочисленный тип и т.д.

Классы основных типов могут быть тривиально извлечены с помощью таких функций, как: mono_get_int32_class(), mono_get_boolean_class() и т.д.