【问题标题】:How to call C++ function takes Vector call from C#如何调用 C++ 函数需要从 C# 调用 Vector
【发布时间】:2023-04-07 11:21:01
【问题描述】:

我正在使用 C++ 并创建分析数据的库。我创建了几个具有采用 C++ 向量的函数的类。现在我想用 C# 创建 UI 并调用这些类。我正在考虑创建从 C# 调用的 API。

既然数据是数组/向量,那么我如何从 C# 中调用它?

【问题讨论】:

  • 当你说 C++ 向量时,你是在说std::vector 那么?
  • 互操作性是一种“高级主题”,但您想要的绝对是可能的。诀窍是围绕您的非托管 c++ clode 创建一个“托管包装器”您可以将 IJW 与 c++\cli [stackoverflow.com/questions/15672351/… 一起使用,或者,如果您调用了 c 样式,请使用 /pinvoke [msdn.microsoft.com/en-us/magazine/cc164123.aspx] 直接链接到 dll。
  • 我正在使用 std::vector 并且在类内部他们大量使用了 BOOST 库。
  • 另一种选择是将 C++ 库包装在 COM 接口中,然后从 C# 中将其添加为引用,自动生成互操作层

标签: c# c++ .net


【解决方案1】:

我本来想发表评论的,但我的代表还不够高。在使用 C++ 的类库中使用 STL 类(例如向量或字符串)时会出现一些复杂情况。您可以在此处查看更多信息和可能的解决方案:I can pass std::string for a Dll and what i can do with DLL´s?

【讨论】:

    【解决方案2】:

    您需要创建自己的 C++/CLI 互操作来实现此目的。

    强烈推荐一本好书,Marcus Heege 的《Expert C++/CLI》,很好读。

    这是我的简短示例:

    // Program.cs
    static void Main(string[] args)
    {
        List<string> someStringList = new List<string>();
        someStringList.Add("Betty");
        someStringList.Add("Davis");
        someStringList.Add("Eyes");
    
        NativeClassInterop nativeClass = new NativeClassInterop();
        string testString = nativeClass.StringCat(someStringList);
    }
    
    // NativeClass.h, skipping this, it's obvious anyways
    
    // NativeClass.cpp, normal C++ class, this was in some DLL project, don't need exports
    #include "stdafx.h"
    #include "NativeClass.h"
    std::string NativeClass::StringCat(std::vector<std::string> stringList)
    {
        std::string result = "";
        for(unsigned int i = 0; i < stringList.size(); i++)
        {
            if(i != 0)
            {
                result += " ";
            }
            result += stringList[i];
        }
        return result;
    }
    
    // NativeClassInterop.cpp, in same DLL project, but compile this file with /clr switch
    #include <gcroot.h>
    #using <System.dll>
    #include <vector>
    #include <string>
    #include "NativeClass.h"
    
    // Helper method
    static std::string nativeStringFromManaged(System::String^ str)
    {
        System::IntPtr hGlobal =
            System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);
    
        std::string nativeString((hGlobal.ToPointer() == 0) 
            ? "" : (char*)hGlobal.ToPointer());
    
        System::Runtime::InteropServices::Marshal::FreeHGlobal(hGlobal);
        return nativeString;
    }
    
    // C++/CLI wrapper class
    public ref class NativeClassInterop
    {
    public:
        System::String^ StringCat(System::Collections::Generic::List<System::String^>^ someStringList)
        {
            // You get to do the marshalling for the inputs
            std::vector<std::string> stringList;
            for(int i = 0; i < someStringList->Count; i++)
            {
                stringList.push_back(nativeStringFromManaged(someStringList[i]));
            }
    
            NativeClass nativeClass;
            std::string nativeString = nativeClass.StringCat(stringList);
    
            // And for the outputs ;-)
            System::String^ managedString = gcnew System::String(nativeString.c_str());
            return managedString;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多