我有一个C函数,它产生一个有趣的矩形列表.我希望能够从C库中获取该列表并返回到调用它的C#应用程序.
到目前为止,我正在编码矩形,如下所示:
struct ImagePatch{ int xmin,xmax,ymin,ymax; }
然后编码一些向量:
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); } }
extern "C" { __declspec(dllexport) void __cdecl MyFunc(...,std::vector<int>& rectanglePoints); }
是否有一些关键字或其他我可以做的东西来取出那组矩形?我在C#中找到了this article用于编组对象,但它看起来太复杂了,而且太不明白了.整数向量是否是正确的方法,或者是否有其他技巧或方法?
解决方法
STL是一个特定于C的库,所以你不能直接将它作为一个对象传递给C#.
保证std :: vector的一点是,& v [0]指向第一个元素,所有元素在内存中线性排列(换句话说,它就像内存布局方面的C数组一样)
所以作为int数组编组…这应该不难 – 网上有很多例子.
假设您只将数据从C传递到C#:
C#无法处理C向量对象,所以不要尝试通过引用传递它:而是你的C代码必须返回一个指向int数组的指针…
如果您不打算从多个线程使用此函数,则可以使用静态存储:
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; }
如果返回的数据大小很大,则调用getRects(true),因此在v中释放内存.
为简单起见,不要传递矢量数据的大小,只需在末尾添加一个sentinel值(比如说-1),这样C#代码就可以检测数据的结束位置.