【问题标题】:Multi-dimensional array of blittable type - how to get pinned unsafe poiner to memory?blittable 类型的多维数组 - 如何获取指向内存的不安全指针?
【发布时间】:2019-05-07 22:33:37
【问题描述】:

假设你有一个

Array array;

假设:

  1. 这个数组的类型是blittable
  2. 该数组在编译时可能有一个任意数量的维度(1..N)未知

基于这些假设,我相信我们可以假设 .Net 框架将其内容存储在内存中的连续区域中。如何获得指向该内存的固定指针

类似于.. 工作版本.. 的东西

// Doesn't work, 
// gives "cannot take the address of the given expression"
fixed(object* ptr = &array.GetValue(0))
{
  // ...
}

// Doesn't work, dimensions unknown at compile-time, 
// so could be T[,], or T[,,], or T[,,,] etc. as well
T[] arr = (T[])array;
fixed(object* ptr = &T[0])
{
  // ...
}

谢谢

【问题讨论】:

  • 这是一个非常有趣的;我正在偷看......但是问题:N 真的 是任意的,还是我们可以合理地假设它在编译时是未知的,但在可预测的范围内,如 1-8 ?另外:我们可以合理地假设它将是基于 0 的吗? (非从零开始的数组让我哭了)
  • 嗨@MarcGravell。对于上下文:这是 IPC 机制的一部分。我正在将来自一个应用程序的数据(在本例中为 SAFEARRAY)序列化为自定义二进制格式,并希望在 C# 应用程序中将其反序列化为常规数组。根据我的协议的定义,它将是基于零的(我拒绝支持基于非零的索引!!;)。尺寸确实是任意的 - 虽然与有人在其他应用程序中创建一些 100 维的安全数组非常不同,但我不能肯定地排除它。

标签: c# arrays memory


【解决方案1】:

你可能正在寻找Marshal.UnsafeAddrOfPinnedArrayElement(如果你只想要根,你可以要求元素0);然而,这里需要注意的是,您需要手动进行固定(可能使用try/finally) - 您不能将fixedArray 一起使用。这比简单的 fixed 引用(它只是“本地”声明上的 IL 标志)具有更多开销


注意:如果你总是在元素 0 的位置之后,那么 GCHandle 上的 AddrOfPinnedObject() 也会给你,而不需要 Marshal 步骤。

【讨论】:

  • 太好了,这看起来很有前途!我会调查一下 - 可能与 GCHandle.Alloc(array, GCHandleType.Pinned) 结合使用
  • @Bogey 供参考,我已经做了一个快速检查,如果您只是在根目录之后,这实际上与handle.AddrOfPinnedObject() 相同......
猜你喜欢
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
相关资源
最近更新 更多