如何将 cli::array 从本机代码转换为本机数组?
Posted
技术标签:
【中文标题】如何将 cli::array 从本机代码转换为本机数组?【英文标题】:How do I convert a cli::array to a native array from native code? 【发布时间】:2011-10-13 19:50:28 【问题描述】:我正在围绕一个用 C++\CLI 编写的托管组件编写本机包装器。
我在托管代码中有以下功能:
array<Byte>^ Class::Function();
我想使用以下签名从本机 C++ 类公开此函数:
shared_array<unsigned char> Class::Function();
我已经从本机代码调用托管函数,但我不确定如何安全地将托管数组复制到非托管数组中。
gcroot<cli::array<System::Byte>^> managedArray = _managedObject->Function();
【问题讨论】:
你希望如何从函数中返回一个不可复制、不可移动的对象? 这是一个很好的观点 - 我想我实际上没有:S。应该是一个 shared_array。 我假设shared_array
来自 boost,对吗?
@R.MartinhoFernandes - 正确。出于这个问题的目的,尽管它可以很容易地成为unsigned char*
。
请注意,如果您使用的是 VC++ 2010(或 VC11 预览版),std::unique_ptr<unsigned char[]>
将是理想的高效返回类型。
【参考方案1】:
通常有两种方法:
使用本机代码执行封送处理,这需要使用pin_ptr<>
:
boost::shared_array<unsigned char> convert(array<unsigned char>^ arr)
boost::shared_array<unsigned char> dest(new unsigned char[arr->Length]);
pin_ptr<unsigned char> pinned = &arr[0];
unsigned char* src = pinned;
std::copy(src, src + arr->Length, dest.get());
return dest;
使用托管代码执行封送处理,这需要使用 Marshal 类:
boost::shared_array<unsigned char> convert(array<unsigned char>^ arr)
using System::Runtime::InteropServices::Marshal;
boost::shared_array<unsigned char> dest(new unsigned char[arr->Length]);
Marshal::Copy(arr, 0, IntPtr(dest.get()), arr->Length);
return dest;
通常我更喜欢后一种方法,因为如果数组很大,前者会阻碍 GC 的有效性。
【讨论】:
我想我会再考虑后一种方法。由于我拥有托管代码的所有权,因此我可以简单地添加一个内部函数以将数据作为 shared_array 返回。 @ildjarn:由于std::copy
是一个模板,它不能与interior_ptr
一起正常工作吗?
@Ben :我不这么认为,因为std::iterator_traits<>
没有专门针对interior_ptr<T>
。【参考方案2】:
看看pin_ptr
,它可以让你将托管类的地址传递给非托管函数。
【讨论】:
以上是关于如何将 cli::array 从本机代码转换为本机数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 pandas 数据框列转换为本机 python 数据类型?