开发者

Wrapping native C++ function with multiple outputs in a .dll for use in C#

开发者 https://www.devze.com 2023-03-20 14:28 出处:网络
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

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:

  1. The function expects pointers to 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?
  2. How do I return multiple values to the managed environment from the wrapper .dll - by using a struct as a return value?
  3. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号