Wrapping native C++ function with multiple outputs in a .dll for use in C#
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:
- The function expects pointers to
output_array
andoutput_value
which need to be created/cleaned-up and returned to the managed component all inside the wrapper. How do I do that? - How do I return multiple values to the managed environment from the wrapper .dll - by using a struct as a return value?
- For now I am trying to do all开发者_开发技巧 the pointer handling and managed/unmanaged interaction inside the wrapper .dll but this article (Solution 3) suggests that using an "unsafe" environment inside C# is the fastest. Is this likely to be a better option for what I am trying to do? I guess it would make the wrapper less complex but also require more elaborate treatment in C#.
Thanks,
/David
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.
精彩评论