Friday, March 24, 2006

Passing arrays from C# to Managed CPP (C++)

In a previous post I had written about how to setup a CPP function, so that it could be called from a C# function and the value be passed in as a reference. (hint: you need to declare the function like this : void ValueByRef (System::Double __gc & data) ) So another question was: How do I send an array from C# to Managed C++? Simple: the definition in MC++ is : void ProcessArray(System::Double data[]) {data[0] = 0; data[1] = 1;} (update: In the same way one can also send in a double dimension array : void ProcessArray(System::Double data[,]) ) And to call it from C# : double []dataArray = new double[3]; mClassObj.ProcessArray(dataArray); My next question is : How do I return an array that was created in MC++? In C++: System::Double ReturnArray()[] //observe the [] at the end! { System::Double data[] = new System::Double[3]; data[0] = 3; data[1] = 33; data[2] = 333; return data; } In C#, call the function like so: double []dataArrayReturned = mClassObj.ReturnArray(); Now we know how to pass an array to a MC++ function and also how to return an array from MC++ to C#. So the next question is : How do I send an array to MC++, have the array created in MC++ and return to CSharp? If you set up the function in MC++ like so: void CreateArray(System::Double data[]), and then initialize the array inside the function, then because the created array was local in scope, it will get destroyed once the function has finished executing. So what we need is a method to pass an array by reference: To do this you need to setup the function like this in MC++: void CreateArrayRef (System::Double (&data)[]) { data = new System::Double[3]; data[0] = 2; data[1] = 22; data[2] = 222; } and call it from C# like this: double []dataArrayByRef = null; mClassObj.CreateArrayRef(ref dataArrayByRef); Ideally though, I would like to call the MC++ function and send the array as an out parameter. Otherwise, C# will complain that I have not initialized the array. (Which is why I had to set the array dataArrayByRef to null) Thus to call a MC++ function like the following from C#: double []dataArrayAsOut; mClassObj.CreateArrayOut(out dataArrayAsOut); You need to setup your MC++ function like this: void CreateArrayOut([Out] System::Double (*data)[]) { *data = new System::Double[3]; System::Double tmp[] = *data; tmp[0] = 1; tmp[1] = 11; tmp[2] = 111; } Remember to include using namespace System::Runtime::InteropServices; at the top, which is where the Out attribute is defined. Hope this answers all questions about passing arrays back and forth between C# and Managed CPP (C++)

1 comment:

Anonymous said...

Hi,

I have some serious problems with managed array as function parameter, maybe you can have a look: http://www.codeguru.com/forum/showthread.php?t=477583