2011-05-19 192 views
3

我对C#的知识非常有限。我的目标是为我的C#同事提供一个C++ dll API。出于传统原因,dll必须使用C++。从C调用C++模板函数#

问题 - C++模板函数(如下面的VS所示)可以用C#编组吗?

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

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

+0

@Yhai这不是同一个问题。 – 2011-05-19 14:09:04

+0

@Yochai:这个问题不是关于移植,而是接口。 LEO仍计划使用C++来构建DLL。甚至不接近愚蠢。 – 2011-05-19 14:09:05

回答

4

问题 - C++模板函数(如下面的VS所示)可以用C#编组吗?

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

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

+0

正确,这不仅影响模板,还影响类。 – 2011-05-19 14:09:58

+0

感谢您的快速回复。我想我会采取Rytmis的想法,并尝试使用C++/CLI开发API – LEO 2011-05-20 13:40:17

4

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

1

所以几个星期后,我能够得到一些东西,我想我会分享给小组。 (赦免伪码外观)。我基本上自学了C#而不是C++/CLI。

记住问题 - C++模板函数(如下面的VS所示)可以用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*)); 
... 
... 

希望帮助!