【问题标题】:Calling C++ template function from C#从 C# 调用 C++ 模板函数
【发布时间】:2011-05-19 13:57:48
【问题描述】:

我对 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# 可以编组它?

【问题讨论】:

  • @Yochai 这不是同一个问题。
  • @Yochai:这个问题不是关于移植,而是关于接口。 LEO 仍计划使用 C++ 来构建 DLL。甚至都不是骗子。

标签: c# c++ templates marshalling


【解决方案1】:

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

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

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

【讨论】:

  • 正确,这不仅会影响模板,还会影响类。
  • 感谢您的快速回复。我想我会采用 Rytmis 的想法并尝试使用 C++/CLI 开发 API
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    所以几周后,我能够让一些东西运行起来,我想我会与小组分享它。 (请原谅伪代码外观)。我基本上是自学 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*));
    ...
    ...
    

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2015-09-22
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多