- 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!
Your answer