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

Marshalling pointer to array P/Invoke

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

不,您不能创建指向已由外部内存管理器分配的非托管内存的 array。但是,您可以创建一个 Span<T> 或一个 Memory<T>,这会给您一个 非常相似的 API,这意味着您不需要unsafe 之后的任何时候。请注意,为了能够将它存储在任何地方,它需要是一个 Memory<T>Span<T> 是一个 ref struct)——但是 Memory<T> 本质上只是一个按需跨度提供商 - 当您需要跨度时,请在您的 Memory<T>.

上调用 .Span

现在;没有 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* 成为一个 byte*,你可以在相同的内存中将 Span<int> 转换成 Span<byte> - 不是副本)。