Как создать универсальный тип .NET в собственном приложении c ++, в котором размещается CLR (без использования C ++ / CLI)? - PullRequest
5 голосов
/ 29 июля 2011

В программах .NET я могу создать универсальный тип с помощью:

 System::Type::MakeGenericType(...)

Должен быть способ сделать это в нативном C ++ для типа .NET (с _TypePtr). Я размещаю свой собственный экземпляр CLR и не использую C ++ / CLI. ( Вот пример того, как это можно сделать .) Мой подход к этому:

_TypePtr BuildGenericType(_TypePtr spGenericType, _TypePtr spTypeArgs[]) 
{
    return spGenericType-> ..... ???
}

Но нет способа, подобного MakeGenericType, и я не знаю, где его найти. Есть идеи, как это решить?

1 Ответ

3 голосов
/ 30 июля 2011

Наконец я нашел обходной путь сам.Сначала мне нужна дополнительная сборка, которая оборачивает System :: TypeBuilder

/// <summary>
/// Wrapper for System::TypeBuilder
/// </summary>
public class TypeBuilder
{
    /// <summary>
    /// Creates a generic type out of the given arguments.
    /// </summary>
    /// <param name="generic">The unqualified generic type.</param>
    /// <param name="typeArgs">The typearguments for the generic type.</param>
    /// <returns>The qualified generic type.</returns>
    public static Type MakeGenericType(Type generic, params Type[] typeArgs)
    {
        return generic.MakeGenericType(typeArgs);
    }
}

Эта дополнительная сборка загружается из c ++

И там я запускаю эти сексуальные строки, где CLRAssembly является слоем абстракции дляclr.

_TypePtr CLRAssembly::BuildType(_TypePtr spGenericType, _TypePtr spTypeArgs[]) 
{
    LONG index = 0;
    SAFEARRAY* psaArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1 + (sizeof(spTypeArgs)/sizeof(_TypePtr)));
    SafeArrayPutElement(psaArgs, &index, &_variant_t((IUnknown*)spGenericType, true));
    for(int i = 0; i < sizeof(spTypeArgs)/sizeof(_TypePtr); i++) {
        index++;
        SafeArrayPutElement(psaArgs, &index, &_variant_t((IUnknown*)spTypeArgs[i], true));
    }

    return (_TypePtr)clraAssemblyHelper->RunMethod(L"AssemblyHelper.TypeBuilder", L"MakeGenericType", psaArgs); 
}

Наконец, я могу запустить мой пример метода следующим образом:

DDDElements::Defs* ListDefs::AddNew()
{
    _TypePtr params[1];
    params[0] = clra->BuildType(L"DDD.Elements.Defs");
    _TypePtr spType = clra->BuildType(clra->BuildType(L"DDD.ElementList`1"), params);
    return new DDDElements::Defs(clr, clra, 
        clra->RunMethod(spType, vtCLRObject, L"AddNew")
    );
}

Наконец, он работает довольно хорошо.:)

/ Решено

...