7

我在 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 导入类中定义。

似乎是,C# 中的 Generic 是托管类型,它与 C++ 中的非托管模板的体系结构完全不同。

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

4

2 回答 2

8

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

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

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

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

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

于 2012-12-29T21:13:30.183 回答
0

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

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

最后在 C# 中,我们也做了同样的事情,使用 T4 为导出的方法生成一个通用包装器。通过这种方式,您可以在 .NET 泛型和 C++ 模板之间架起一座桥梁,同时充分利用 C++ 模板的强大功能

于 2013-09-18T10:43:57.477 回答