Reputation: 936
I am wrapping some native C++ code in a C++/CLI .dll for use in .NET projects - mainly C#. The number of calls will be large so I am looking to do this in an effective way. The function I am wrapping takes the following arguments:
int SomeFun(
const char* input_text,
int* output_array,
bool* output_value);
I know how to do an efficient System::String
to const char*
cast thanks to this answer. My questions are these:
output_array
and output_value
which need to be created/cleaned-up and returned to the managed component all inside the wrapper. How do I do that?Thanks,
/David
Upvotes: 2
Views: 1004
Reputation: 11230
You can pin arrays the same way you pin strings, e.g. for byte[]:
pin_ptr<Byte> ptrBytes = &myArray[myArray->GetLowerBound(0)];
ptrBytes can now be used as an unsigned char*
You can pin single variables that come from C#, too, for example with a parameter that is a ref to an int called int% ival:
pin_ptr<int> pInt = &ival;
pInt can now be used as an int*
You can create arrays with gcnew, for example to create an array of Bytes to return to C#:
array<Byte>^ streambuf = gcnew array<Byte>(bufSize+16);
You can now fill this with streambuf[index], repacking a C++ array in a loop, or you could pin it and do a memcpy before returning it to C#.
I do not usually return structs. I usually define each parameter in the C++/CLI function wrapper. For example if a struct had two ints and a string, I'd make each a parameter with ref keyword (% in C++/CLI, e.g. int% ival). if you must return a large number of values it's easiest to return a class you create with gcnew, not a struct.
Using unsafe code is the way to go if you are trying to speed up array access and your C# code will be straightforward. If you already have C++ code and it uses the STL and is very complex and you don't want to rewrite it, especially if you have lots of pointer arithmetic and casts, stick with a C++/CLI wrapper.
Upvotes: 1