【问题标题】:C# -- Create Managed Array from PointerC# -- 从指针创建托管数组
【发布时间】:2009-12-16 17:17:17
【问题描述】:

我正在尝试从一个字节数组创建一个托管数组。我目前有问题,但我想优化。这是我想要使用的一些代码:

private unsafe static double[] _Get_Doubles(byte[] _raw_data)
{
    double[] ret;
    fixed (byte* _pd = _raw_data)
    {
        double* _pret = (double*)_pd;
        ret = (double[])*_pret; //FAILURE
    }
}

请告诉我如何处理这些问题。

-亚伦

【问题讨论】:

  • 通常在处理 Interop 时,Marshaller 是您的朋友,在 System.Runtime.InteropServices.Marshal 为您服务。我不知道使用数组具体需要什么。但是,您可以使用指针算法访问数组。也许这会提示您走向正确的方向。
  • @daGhost -- 我当然知道使用指针访问数组,但我必须研究编组托管数组。谢谢。
  • @Limited Thing(请不要再叫我daGhost):如果您可以使用指针访问数组元素,则可以将值复制到托管数组中。

标签: arrays pointers unmanaged managed


【解决方案1】:

关于您发布的代码,需要注意的关键事项之一是无法知道返回值指向了多少项,托管数组需要知道它有多大。您可以返回 double* 或创建 new double[XXX] 并复制值,甚至(如果计数不变)创建带有 public fixed double _data[2]; 成员的 struct 并将原始数据转换为该类型。

【讨论】:

  • 这基本上就是我最终要做的。我创建了一个固定长度的双精度数组,然后一次将我的值复制到那里。最好以 C++ 方式不分配新的双精度数组。是的,一个带有 double[] 和 byte[] 的结构设置为像 al、ax 和 eax 寄存器一样重叠,但是创建结构的开销可能比我正在做的要多……这可能会让你想一想,你到底为什么要在你的数组复制中如此复杂?我回答''。
【解决方案2】:

刚才,我认为stackalloc 是正确的方法,但它失败了。最重要的是,我现在知道它注定要失败。没有办法做我想做的事。

这可以通过重述问题来看出:

如何围绕“不安全”数组创建托管数组?

由于托管数组具有标头信息(因为它是一个围绕大量内存的类),所以它需要比数组本身更多的内存空间。所以,答案是:

在数组本身之前(和/或之后?取决于托管数组在内存中的存储方式)分配空间,并将托管信息(长度等)放在“不安全”数组周围。

这并不容易,因为保证数组周围有足够的数据充其量是不稳定的。在我的特定示例中,它可能有足够的空间,因为传递了托管 byte[] 意味着数组周围有数据,但是断言相同的数据适用于托管 double[] 充其量是可疑的,但大多数可能是错误的,并且更改数据以使其适合托管 double[] 是邪恶的。

[编辑]

看起来Marshal.Copy 是这里的路。创建一个新数组并让 Marshal 复制它们(希望他会比我快,或者也许在以后的某个时间,他会更快):

var ret = new double[_raw_data.Length / sizeof(double)];
System.Runtime.InteropServices.Marshal.Copy(new System.IntPtr(_pret), ret, 0, ret.Length);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    相关资源
    最近更新 更多