- Home /
Passing large Vector array to native plugin without copying
Hey, I'm wondering how I can pass a large array of Vector3s to a C++ plugin without the marshaller copying the data. This is what I'm currently doing.
[DllImport ("NativeLibrary")]
private static extern void PopulateVerts([In, Out] Vector3[] verts);
Vector3[] verts = new Vector3[20000];
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
PopulateVerts(verts);
stopwatch.Stop();
Debug.Log("Populate Verts: " + stopwatch.Elapsed);
and on the C++ side I have this
struct Vert
{
float x,y,z;
};
extern "C" void EXPORT_API PopulateVerts(Vert* verts)
{
}
It's taking 0.002 seconds to send the array to C++ which leads me to believe that the marshaller is copying the data. Is there any way to just pass a pointer to the array and modify the values in C++ without actually copying the data over the managed/unmanaged barrier?
Answer by whydoidoit · Jul 05, 2012 at 04:25 AM
You can pin the object in memory using a GCHandle and then pass the address to the C++ function. See this for allocating a pinned GCHandle.
Brilliant! Thank you! Went from 0.002 seconds down to 0.000002 seconds. Great tip!
Answer by stevesan · Aug 05, 2017 at 03:24 PM
I have done this by just passing a ref to the first element of the array. So something like:
In C: void nativeFunc(float* firstElem);
Then in C#: void nativeFunc(ref float firstElem);
Then to call: float[] myFloats = new float[123]; nativeFunc(ref myFloats[0]);
Not sure how kosher this is..and definitely your native code should not save the pointer across calls!