I have a C# front end and a C++ backend for performance reasons. Now I would like to call a C++ function like for example:
void findNeighbors(Point p, std::v
Or write your wrapper in C++/CLI. Have it take a CLS-compliant type such as IEnumerable and then (sigh) copy each element into your vector, then call the PInvoke.
The best solution here is to write a wrapper function in C which is limited to non-C++ classes. Non-trivial C++ classes are essentially unmarshable via the PInvoke layer [1]. Instead have the wrapper function use a more traditional C signature which is easy to PInvoke against
void findNeigborsWrapper(
Point p,
double maxDist,
Point** ppNeighbors,
size_t* pNeighborsLength)
[1] Yes there are certain cases where you can get away with it but that's the exception and not the rule.
In order to reduce overhead from copying (if that does cause performance problems) it would be possible to write a C++/CLI ref class around std::vector<>. That way the c++ algorithm can work on c++ types and C# code can access the same data without excessive copying.
The C++/CLI class could implement operator[] and Count in order to avoid relying on IEnumerable::GetEnumerator ().
The impedance mismatch is severe. You have to write a wrapper in the C++/CLI language so that you can construct a vector. An additional problem is Point, your C++ declaration for it is not compatible with the managed version of it. Your code ought to resemble this, add it to a class library project from the CLR node.
#include <vector>
using namespace System;
using namespace System::Collections::Generic;
struct Point { int x; int y; };
void findNeighbors(Point p, std::vector<Point> &neighbors, double maxDist);
namespace Mumble {
public ref class Wrapper
{
public:
List<System::Drawing::Point>^ FindNeigbors(System::Drawing::Point p, double maxDist) {
std::vector<Point> neighbors;
Point point; point.x = p.X; point.y = p.Y;
findNeighbors(point, neighbors, maxDist);
List<System::Drawing::Point>^ retval = gcnew List<System::Drawing::Point>();
for (std::vector<Point>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
retval->Add(System::Drawing::Point(it->x, it->y));
}
return retval;
}
};
}
Do note the cost of copying the collection, this can quickly erase the perf advantage you might get out of writing the algorithm in native C++.