How to call an unmanaged C++ function with a std::vector::iterator as parameter from C#? -



How to call an unmanaged C++ function with a std::vector<>::iterator as parameter from C#? -

in unmanaged c++ have function i'm trying phone call c#. c++ function 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 c++, function used 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 convex hull" << std::endl;

i've started writing c# code, i've no thought types should passing:

[dllimport("unmanagedcode.dll", entrypoint = "convexhull", callingconvention = callingconvention.stdcall)] public static extern ???<point> convex_hull_2(???<point> start, ???<point> last, ???<point> result);

the point construction in c# just:

struct point{ double x; double y; }

is case of passing array or list of point?

i have source c++ , can create changes function parameters; there different type of parameters easier phone call c#?

passing c++ types through p/invoke not going work. don't know layout , nil guarantees won't change. p/invoke meant inter-operating c.

one alternative utilize c++/cli instead of c++. won't portable (only supported vc++/windows), might easiest solution depending on how big c++ code already.

if want remain portable , utilize straight p/invoke c#, best bet refactor c++ convexhull , provide new function callable c (and p/invoke).

// c-safe struct. struct results { point *points; std::size_t num_points; }; // store real results in vector, derive c-safe struct. struct resultsimpl : results { points storage; }; // convexhull has been refactored take pointers // instead of vector iterators. outputiterator convexhull(point const *first, point const *last, outputiterator result); // exported function callable c. // returns c-safe results, not resultsimpl. extern "c" dllexport results* convexhullc(point const *points, std::size_t num_points) { seek { std::unique_ptr<resultsimpl> r(new resultimpl); // fill in r->storage. convexhull(points, points + num_points, std::back_inserter(r->storage)); // fill in c-safe members. r->points = &r->storage[0]; r->numpoints = &r->storage.size(); homecoming r.release(); } catch(...) { // trap exceptions! homecoming 0; } } // needs called c# clean results. extern "c" dllexport void freeconvexhullc(results *r) { seek { delete (resultsimpl*)r; } catch(...) { // trap exceptions! } }

and c#:

[structlayout(layoutkind.sequential)] struct point { double x; double y; } [structlayout(layoutkind.sequential)] struct results { intptr points; intptr num_points; } [dllimport("unmanagedcode")] intptr convexhullc(point[] points, intptr pointcount); [dllimport("unmanagedcode")] void freeconvexhullc(intptr results); point[] convexhull(point[] points) { intptr pr = convexhull(points, new intptr(points.length)); if(pr == intptr.zero) { throw new exception("native error!"); } seek { results r = marshal.ptrtostructure(pr, typeof(results)); points = new point[checked((int)(long)r.num_points)]; for(int = 0; < points.length; ++i) { points[i] = marshal.ptrtostructure( r.points + marshal.sizeof(typeof(point)) * i, typeof(point)); } homecoming points; } { freeconvexhull(pr); } }

code not tested!

c# c++ pinvoke

Comments

Popular posts from this blog

iphone - Dismissing a UIAlertView -

intellij idea - Update external libraries with intelij and java -

javascript - send data from a new window to previous window in php -