как использовать MonoType в контексте оценки сигнатур методов - PullRequest
0 голосов
/ 27 октября 2011

Я хочу иметь возможность вызывать методы классов 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. сравнить список параметров метода с другим списком, предоставленным в качестве входных данных для функции
    • не может сравнивать по enum, так как не может получить доступ к полю enum (см. Выше)
  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, &iter))
    {
        if (!IsEquivalent (type, types[i++]->this_arg))
            return false;
    }

    return true;
}

1 Ответ

2 голосов
/ 28 октября 2011

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

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

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

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

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

...