如何调用c++函数从c#中获取Vector调用

本文关键字:调用 Vector 获取 函数 c++ 何调用 | 更新日期: 2023-09-27 18:16:14

我正在用c++工作,并创建分析数据的库。我创建了几个类,这些类的函数采用c++向量。现在我想在c#中创建UI并调用这些类。我正在考虑创建API从c#调用。

既然数据是数组/向量,那么我怎么能从c#调用它?

如何调用c++函数从c#中获取Vector调用

我本想发表评论,但我的知名度不够高。在c++类库中使用STL类(如vector或string)会有一些复杂性。您可以在这里查看更多信息和可能的解决方案:我可以为Dll传递std::string,我可以用Dll ´s做些什么?

您需要创建自己的c++/CLI互操作来实现这一点。

强烈推荐一个不错的书,"专家c++/CLI"马库斯Heege,非常值得一读。

下面是我简短的例子:

// 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;
    }
};