如何在托管CLR的本机c++应用程序中创建通用的.NET类型(不使用c++ /CLI)?

时间:2022-02-23 18:44:30

In .NET programs I can create a generic type by:

在。net程序中,我可以创建一个泛型类型:

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

There must be a way to do that in native C++ for a .NET type (with _TypePtr). I am hosting my own CLR instance and not using C++/CLI. (Here's an example of how that can be done.) My approach for that is:

对于. net类型(带有_TypePtr),必须有一种在本机c++中实现这一点的方法。我托管自己的CLR实例,不使用c++ /CLI。(这是一个如何做到这一点的例子。)我的方法是:

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

But there is no method like MakeGenericType, and I don't know where to find it. Any ideas on how to solve this?

但是没有像MakeGenericType这样的方法,我不知道在哪里找到它。有什么办法解决这个问题吗?

1 个解决方案

#1


3  

Finally i found a workaround myself. At first i need an additional assembly that wraps System::TypeBuilder

最后我自己找到了解决办法。首先,我需要一个封装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);
    }
}

This additional assemly i load from c++

我从c++加载这个附加的汇编程序

And there i run these sexy lines, where CLRAssembly is an abstraction layer for clr.

在这里,我运行这些性感的线条,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); 
}

Finally i can run my example method like this:

最后我可以运行我的示例方法如下:

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

Finally it works pretty good. :)

最后,它的效果非常好。:)

/Solved

/解决

#1


3  

Finally i found a workaround myself. At first i need an additional assembly that wraps System::TypeBuilder

最后我自己找到了解决办法。首先,我需要一个封装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);
    }
}

This additional assemly i load from c++

我从c++加载这个附加的汇编程序

And there i run these sexy lines, where CLRAssembly is an abstraction layer for clr.

在这里,我运行这些性感的线条,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); 
}

Finally i can run my example method like this:

最后我可以运行我的示例方法如下:

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

Finally it works pretty good. :)

最后,它的效果非常好。:)

/Solved

/解决