【问题标题】:Native types and Generics本机类型和泛型
【发布时间】:2026-01-25 08:25:01
【问题描述】:

我想创建一个原生数组并访问它的托管代码。我不想将代码重写为不同的类型,(intlongfloatdouble)因此尝试使用泛型。

typedef int IND;

generic <typename T>
public ref class ntvarray
{
    void *pnt;
    IND sz;

public:
    ntvarray(IND length)
    {
        sz = sizeof(T);
        pnt =  ::operator new(length*sz);
    }

    ~ntvarray()
    {
        ::operator delete(pnt);
    }

    void* pointer()
    {
        return pnt;
    }

    T getitem (IND index)
    {
        //c3229
        return ((T*)pnt)[index];
    }

    void setitem (IND index, T value)
    {
        //c3229
        ((T*)pnt)[index] = value;
    }
};

我收到了这个错误,我知道这个错误的原因,

错误 C3229:'T *':不允许对泛型类型参数进行间接访问

但是有没有办法使用泛型来做到这一点?除了使用泛型之外,还有其他方法可以做到这一点吗?

【问题讨论】:

    标签: generics reflection c++-cli managed native-code


    【解决方案1】:

    不,您不能使用泛型来做到这一点。但是你可以使用模板。这避免了您的问题所强调的代码重复,但不会像泛型那样允许运行时实例化。

    【讨论】:

    • 其实我想在托管代码中重用这个类的几种类型,而不需要重复代码。除了泛型,我没有看到任何其他方式。但是泛型也不支持专业化。 :(
    • 而托管代码链接这段代码是c#,不能使用模板类。引用具有上述代码的程序集的 C# 代码如何访问模板类?
    • @Annifer:是的,这很不幸。我假设使用它的 C# 代码也是通用的?我要做的是 (1) 声明一个通用 interface class (2) 将此代码更改为模板并使其实现通用接口 (3) 创建一个工厂函数,该函数接受 System.Type 并创建一个新的匹配对象(这将导致所有模板变体的实例化)。 C# 不会关心这个类是用模板创建的,因为它知道如何使用通用接口。
    • 好的!有用!谢谢。工厂函数完成了这项工作。然而,它的速度比非通用版本慢一倍……正如预期的那样。
    • @Annifer:希望只有创建慢,然后使用界面就很快了?但是,是的,通过接口调用可能会稍微慢一些,因为 JIT 编译器内联要困难得多。