I want to pass around 100 - 10,000 Points from an unmanaged C++ to C#.
The C++ side looks like this:
__declspec(dllexport) void detect_targets( char * , int , /* More arguments */ )
{
std::vector<double> id_x_y_z;
// Now what's the best way to pass this vector to C#
}
Now my C# side looks like this:
using System;
using System.Runtime.InteropServices;
class HelloCpp
{
[DllImport("detector.dll")]
public static unsafe extern void detect_targets( string fn , /* More arguments */ );
static void Main()
{
detect_targets("test.png" , /* More arguments */ );
}
}
How do I need to alter my code in order to pass the std::vector from unmanaged C++ with all it's content to C#?
As long as the managed code does not resize the vector, you can access the buffer and pass it as a pointer with
vector.data()
(for C++0x) or&vector[0]
. This results in a zero-copy system.Example C++ API:
Caller:
I implemented this using C++ CLI wrapper. C++ CLI is one the three possible approaches for C++ C# interop. The other two approaches are P/Invoke and COM. (I have seen a few good people recommend using C++ CLI over the other approaches)
In order to marshall information from native code to managed code, you need to first wrap the native code inside a C++ CLI managed class. Create a new project to contain native code and its C++ CLI wrapper. Make sure to enable the
/clr
compiler switch for this project. Build this project to a dll. In order to use this library, simply add its reference inside C# and make calls against it. You can do this if both projects are in the same solution.Here are my source files for a simple program to marshal a
std::vector<double>
from native code into C# managed code.1) Project EntityLib (C++ CLI dll) (Native Code with Wrapper)
File NativeEntity.h
File NativeEntity.cpp
File ManagedEntity.h (Wrapper Class)
File ManagedEntity.cpp
2) Project SimpleClient (C# exe)
I could think of more than one option, but all include copying the data of the array anyways. With [out] parameters you could try:
C++ code
C# code