从C#调用C ++模板函数

时间:2011-05-19 13:57:48

标签: c# c++ templates marshalling

我对C#的了解非常有限。我的目标是为我的C#同事提供一个C ++ DLL API。由于遗留原因,dll必须使用C ++。

问题 - 可以在C#中封送C ++模板函数(如下所示)吗?

class  __declspec(dllexport) Foo
{
public: 
    template <typename T> T* getFoo(T* fooData){return fooData;};
};

如果没有,有什么建议吗?传递给模板函数的每个类型是否都有自己的函数,因此C#可以编组它吗?

3 个答案:

答案 0 :(得分:4)

  

问题 - 可以在C#中封送C ++模板函数(如下所示)吗?

没有。从C#到C ++没有兼容的二进制接口。您只能从C#中调用导出的C符号。

理论上,您可以显式实例化C ++ DLL中的模板,这将导致它们在导出符号表中获取外部链接和条目。但名称修改将使功能无法用于所有实际目的。因此,最好的方法是使用一个中间的C兼容层来调用底层的C ++函数。

答案 1 :(得分:4)

我认为您最好的选择是在C++/CLI中编写代码。您可以公开可由C#代码使用的托管API,但在需要时仍使用本机C ++。

答案 2 :(得分:1)

所以几周之后我就能得到一些东西,我想我会和小组分享。 (原谅伪代码外观)。我基本上自学C#而不是C ++ / CLI。

记住问题 - 可以在C#中封送C ++模板函数(如下所示)吗?

我的工作如下:对C ++函数进行编组的非托管C#调用,可以将调用转换为模板方法。

以下是代码:

//C++ code
//C++ Header
class  __declspec(dllexport) Foo
{
    public: 
        template <typename T> T* getFoo(T* fooData){return fooData;};
};

extern "C" __declspec(dllexport) void call_getFoo(Foo* pFoo, void* pfooData, int fooId)
{
    switch(fooId)
    {
        case(ENUM::1) : //Use an enum here for a better switch statement.       
        {   
            //Cast the void pointer to a specific type so the template knows how to use it.
            pFoo->getFoo((*TypeCast*)pfooData);
        break;
        }
    }
}

//C# Code
internal static class UnsafeNativeMethods
{
    const string _dllLocation = "Foo.dll";

    [DllImport(_dllLocation)]
    static public extern void call_getFoo(IntPtr pFoo, IntPtr pfooData, int fooId);           
}

//In a C# method
...
...
//Marshal Up a C# data type to a pointer for C++.
*YOUR TYPE HERE* myType;
int rawsize = Marshal.SizeOf(myType);
IntPtr pfooData = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(myType,pfooData,true);

//call the C++ dll
UnsafeNativeMethods.call_getFoo(pFoo, pfooData, fooId);

//Convert Ptr Back To myType
myType = (*YOUR TYPE HERE*) Marshal.PtrToStructure(pfooData, typeof(*YOUR TYPE HERE*));
...
...

希望有所帮助!