P /从C#</t>调用C ++模板<t>方法

时间:2012-12-29 18:30:44

标签: c# c++ templates generics pinvoke

我已在C ++函数中定义了外部调用:

template<typename T>
void __declspec(dllexport) SwapMe(T *fisrt, T *second)
{
    std::cout << typeid(T).name() << std::endl;

    T temp = *first;
    *first = *second;
    *second = temp;
}

我想在C#程序中使用它。我试过这样的方式:

unsafe class Program
{
    [DllImport("lib1.dll", EntryPoint = "SwapMe")]
    static extern void SwapMe<T>(T first, T second);

    ...
}

但是,我收到了这样的错误:

泛型类中的通用方法或方法是内部调用,PInvoke,或在COM Import类中定义。

似乎是,C#中的Generic是托管类型,而且在C ++中使用非托管模板的架构是相当不同的东西。

如何在C#程序中使用模板方法?

2 个答案:

答案 0 :(得分:8)

C ++编译器不会将模板函数烧录到二进制文件中。只发出专门版本。 C ++编译器在逻辑上克隆模板定义,并用所需的具体类型替换T

这意味着您必须创建一个专门的包装器:

void __declspec(dllexport) SwapMe(int *fisrt, int *second) { //example
{ SwapMe(first, second); }

你可以用C#调用这个,但你不能调用模板版本。

C ++模板和C#泛型的工作方式截然不同。

答案 1 :(得分:0)

为了补充上述内容,我们最近经历了这个并使用T4(TextTransform.exe)为C ++中的包装器生成模板。

为此,我们在C ++项目中包含了一个T4文件,并且对于每种类型的args组合,都围绕C ++模板方法生成了一个包装器方法。然后导出包装器方法。

最后在C#中我们做了同样的事情,使用T4生成围绕导出方法的通用包装器。通过这种方式,您可以在利用C ++模板的完整功能的同时弥合.NET Generics和C ++模板之间的鸿沟