包装原生 C++ .dll 中具有多个输出的函数,以便在 C# 中使用
我将一些本机 C++ 代码包装在 C++/CLI .dll 中,以便在 .NET 项目中使用 - 主要是 C#。通话数量会很大,因此我希望以有效的方式做到这一点。我包装的函数采用以下参数:
int SomeFun(
const char* input_text,
int* output_array,
bool* output_value);
由于 答案。我的问题是:
- 该函数需要指向
output_array
和output_value
的指针,这些指针需要在包装器内创建/清理并返回到托管组件。我该怎么做? - 如何通过使用结构体作为返回值,从包装器 .dll 将多个值返回到托管环境?
- 现在,我正在尝试在包装器 .dll 内执行所有指针处理和托管/非托管交互,但是 本文(解决方案 3)建议在 C# 内部使用“不安全”环境是最快的。对于我想做的事情来说,这可能是更好的选择吗?我想这会使包装器不那么复杂,但也需要在 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以像固定字符串一样固定数组,例如对于 byte[]:
ptrBytes 现在可以用作 unsigned char*
您也可以固定来自 C# 的单个变量,例如使用作为引用的参数int 称为 int% ival:
pInt 现在可以用作 int*
您可以使用 gcnew 创建数组,例如创建一个字节数组以返回到 C#:
您现在可以用以下内容填充它Streambuf[index],在循环中重新打包 C++ 数组,或者您可以固定它并在将其返回到 C# 之前执行 memcpy。
我通常不返回结构。我通常在 C++/CLI 函数包装器中定义每个参数。例如,如果一个结构有两个 int 和一个字符串,我将使用 ref 关键字(C++/CLI 中的 %,例如 int% ival)为每个参数创建一个参数。如果必须返回大量值,最简单的方法是返回使用 gcnew 创建的类,而不是结构体。
如果您想加快数组访问速度并且您的 C# 代码很简单,那么使用不安全代码是一种可行的方法。如果您已经有 C++ 代码,并且它使用 STL 并且非常复杂,并且您不想重写它,特别是如果您有大量指针算术和强制转换,请坚持使用 C++/CLI 包装器。
You can pin arrays the same way you pin strings, e.g. for byte[]:
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:
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#:
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.