In unmanaged C++ I have a function which I’m trying to call from C#. This C++ function is as follows:
typedef std::vector<Point> Points;
typedef std::back_insert_iterator<Points> OutputIterator;
namespace MYNAMESPACE{
DLLEXPORT OutputIterator convexHull(Points::iterator first, Points::iterator last, OutputIterator result);
}
When called from C++, the function is used as follows:
Points points, result;
points.push_back(Point(0,0));
points.push_back(Point(10,0));
points.push_back(Point(10,10));
points.push_back(Point(6,5));
points.push_back(Point(4,1));
OutputIterator resultIterator = std::back_inserter(result);
MYNAMESPACE::convexHull( points.begin(), points.end(), resultIterator);
std::cout << result.size() << " points on the convex hull" << std::endl;
I’ve started writing the C# code, but I’ve no idea what types I should be passing:
[DllImport("unmanagedCode.dll", EntryPoint = "convexHull", CallingConvention = CallingConvention.StdCall)]
public static extern ???<Point> convex_hull_2(???<Point> start, ???<Point> last, ???<Point> result);
The Point structure in C# is just:
struct Point{
double x;
double y;
}
Is it a case of passing an array or List of Point?
I have the source to the C++ and can make changes to the function parameters; would there be a different type of parameters which would be easier to call from C#?
Passing C++ types through P/Invoke is not going to work. You don’t know their layout and nothing guarantees they won’t change. P/Invoke is really only meant for inter-operating with C.
One option is to use C++/CLI instead of C++. This won’t be portable (only supported with VC++/Windows), but it might be the easiest solution depending on how large your C++ code is already.
If you want to remain portable and use straight P/Invoke from C#, your best bet is to slightly refactor the C++
convexHulland provide a new function callable from C (and thus P/Invoke).And then from C#:
Code not tested!