2011-07-29 8 views
5

En programas .NET que puede create a generic type por:Cómo crear un tipo .NET genérico en una aplicación nativa de C++ que hospeda el CLR (sin usar C++/CLI)?

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

Tiene que haber una manera de hacer que en C++ nativo para un tipo .NET (con _TypePtr). Estoy alojando mi propia instancia CLR y no uso C++/CLI. (. Here's an example of how that can be done) Mi enfoque para esto es:

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

Pero no existe un método como MakeGenericType, y no sé dónde encontrarlo. ¿Alguna idea sobre cómo resolver esto?

+0

He etiquetado este C++/CLI, porque creo que es la única forma en que tiene sentido. Corrígeme si estoy equivocado. –

+0

no cli es un clr alojado. –

+0

@nemcija: Es realmente raro hacer eso, y edité su pregunta para mencionarlo. – Puppy

Respuesta

3

Finalmente encontré una solución yo mismo. Al principio Necesito un montaje adicional que envuelve Sistema :: 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); 
    } 
} 

Este assemly adicional i carga de C++

Y no corro estas líneas atractivas, donde ClrAssembly es una capa de abstracción para el 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); 
} 

fin puedo ejecutar mi método ejemplo como este:

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") 
    ); 
} 

Por último funciona bastante bien. :)

/Resuelto

Cuestiones relacionadas