如何将vector <int>从C++ dll编组到C#应用程序?

mmr*_*mmr 8 .net c# c++ stl marshalling

我有一个C++函数,它生成一个有趣的矩形列表.我希望能够从C++库中获取该列表并返回到调用它的C#应用​​程序.

到目前为止,我正在编码矩形,如下所示:

struct ImagePatch{ 
   int xmin, xmax, ymin, ymax;
}
Run Code Online (Sandbox Code Playgroud)

然后编码一些向量:

void MyFunc(..., std::vector<int>& rectanglePoints){
   std::vector<ImagePatch> patches; //this is filled with rectangles
   for(i = 0; i < patches.size(); i++){
       rectanglePoints.push_back(patches[i].xmin);
       rectanglePoints.push_back(patches[i].xmax);
       rectanglePoints.push_back(patches[i].ymin);
       rectanglePoints.push_back(patches[i].ymax);
   }
}
Run Code Online (Sandbox Code Playgroud)

用于与C#交互的标题看起来像(并且适用于许多其他函数):

extern "C" {
    __declspec(dllexport) void __cdecl MyFunc(..., std::vector<int>& rectanglePoints);
}
Run Code Online (Sandbox Code Playgroud)

是否有一些关键字或其他我可以做的东西来取出那组矩形?我发现这篇文章用于在C#中编组对象,但它看起来太复杂了,太过于缺乏解释.整数向量是正确的方法,还是有其他技巧或方法?

rep*_*vsd 5

STL 是一个特定于 C++ 的库,因此您不能将它作为一个对象直接传递给 C#。

关于 std::vector 保证的一件事是 &v[0] 指向第一个元素,并且所有元素都线性地位于内存中(换句话说,就内存布局而言,它就像一个 C 数组)

所以 marshal 作为 int 数组......这应该不难 - 网上有很多例子。

添加

假设您只将数据从 C++ 传递到 C#:

C# 无法处理 C++ 向量对象,因此不要尝试通过引用传递它:相反,您的 C++ 代码必须返回一个指向整数数组的指针...

如果您不打算从多个线程使用此函数,则可以使用静态存储:

int *getRects(bool bClear)
{
    static vector<int> v; // This variable persists across invocations
    if(bClear)
    {
        v.swap(vector<int>());
    }
    else
    {
        v.clear();
        // Fill v with data as you wish
    }

    return v.size() ? &v[0] : NULL;
}
Run Code Online (Sandbox Code Playgroud)

如果返回的数据大小显着,则调用 getRects(true),因此您释放 v 中的内存。

为简单起见,不要传递矢量数据的大小,只需在末尾放置一个标记值(例如 -1),以便 C# 代码可以检测数据的结束位置。


Ste*_*eve 0

我很确定你不能这样做。您必须能够将 C++ 代码直接转换为 C# 类,因此您至少必须复制向量类的内部结构才能正确编组它。我也很确定您将无法跨边界移动引用,您必须使用 IntPtr (原始指针)。我知道有效的方法是编组结构的原始数组。