编组指向数组P / Invoke的指针

时间:2018-07-28 04:22:51

标签: c# arrays .net-core pinvoke marshalling

我正在使用(FFTW)将共享对象库.NET包装在P/Invoke Core中。 FFTW需要分配可能在特定边界上对齐的内存,因此我需要使用其内存分配例程。理想情况下,我想避免在托管数组中创建单独的内存块,并避免每次使用时复制数据。理想情况下,创建数组以指向已分配的内存。这是可能的,还是我应该放弃并承担副本的性能问题?

1 个答案:

答案 0 :(得分:4)

否,您不能创建一个 array 来指向由外部内存管理器分配的非托管内存。但是,您可以创建一个Span<T>或一个Memory<T>来创建一个{em>非常相似的API ,这意味着您根本不需要unsafe之后点。请注意,要能够将其存储在任何地方,它必须是Memory<T>Span<T>ref struct)-但是Memory<T>本质上只是按需跨度提供程序-如果需要跨度,请在.Span上致电Memory<T>

现在;没有Memory<T>用于处理开箱即用的原始指针,但是编写一个简单。或者,您也可以只使用this one I wrote earlierMemoryManager<T>是一种抽象,可用于实现自定义Memory<T>实例,然后在需要时提供Span<T>)。

用法:

int* ptr = ...
int len = ...

var memory = new UnmanagedMemoryManager<int>(ptr, len).Memory;
// (I should probably add a helper method for that!)

为您提供一个Memory<int>,您可以将其存储在字段等中;然后使用它,您需要跨度:

var span = _memory.Span;
span[42] = 119; // etc

您还可以执行跨范围的强制类型转换之类的操作,从而使它们能够执行指针可以执行的大多数相同操作(即,以与您可以将int*强制为{{1} },您可以将byte*转换为Span<int>(在同一内存上-而不是副本)。