从 C# 调用C++模板函数
本文关键字:函数 C++ 调用 | 更新日期: 2023-09-27 17:57:03
我对C#的了解非常有限。我的目标是为我的 C# 同事提供一个C++ dll API。出于旧原因,dll 必须处于C++状态。
问题 - 是否可以在 C# 中封送C++模板函数(下面从 VS 中显示)?
class __declspec(dllexport) Foo
{
public:
template <typename T> T* getFoo(T* fooData){return fooData;};
};
如果没有,有什么建议吗?传递给模板函数的每个类型是否都应该有自己的函数,以便 C# 可以封送它?
问题 - 是否可以在 C# 中封送C++模板函数(如下所示的 VS)?
不。从 C# 到 C++ 没有兼容的二进制接口。只能从 C# 调用导出的 C 符号。
理论上,可以在C++ DLL 中显式实例化模板,这将导致它们在导出符号表中获取外部链接和条目。但是名称重整会使函数无法用于所有实际目的。因此,最好的方法是有一个中间的C兼容层来调用底层C++函数。
我认为你最好的选择是用 C++/CLI 编写代码。可以公开可由 C# 代码使用的托管 API,但在需要时仍使用本机C++。
所以几周后,我能够运行一些东西,我想我会与小组分享。(请原谅伪代码外观)。我基本上自学了C#而不是C++/CLI。
记住问题 - 是否可以在 C# 中封送 C++ 模板函数(如下所示的 VS)?
我的解决方法如下:对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*));
...
...
希望对您有所帮助!