2009-12-16 47 views
7

我想从字节数组创建一个受管阵列的双打。我目前遇到问题,但我想优化。这里有一些代码,我想工作:C# - 从指针创建受管阵列

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

请让我知道如何应对这些问题。

-Aaron

+0

一般与互操作问题时,现Marshaller就是你朋友,在您的服务在System.Runtime.InteropServices.Marshal。我不知道具体你需要什么使用数组。但是,您可以使用指针算术来访问数组。也许这提示你进入正确的方向。 – OregonGhost 2009-12-16 17:27:32

+0

@daGhost - 我当然知道使用指针访问数组,但我不得不考虑编组托管数组。谢谢。 – 2009-12-16 18:16:46

+0

@Limited Thing(请不要再打电话给我的daGhost):如果可以用指针访问数组元素,可以将值复制到托管数组中。 – OregonGhost 2009-12-17 09:22:54

回答

2

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

这可以通过重申这个问题可以看出:

如何创建围绕“不安全”的阵列管理的阵列?

由于托管数组具有标头信息(因为它是围绕内存卡盘的类),因此它需要比阵列本身更多的内存空间。因此,答案是:

在(和/或之后?取决于托管数组存储在内存中的方式)分配阵列本身的空间并将托管信息(长度(等等))放在'unsafe '阵列。

这并不容易,因为要保证阵列周围的数据不够充其量。在我的具体例子中,可能有足够的空间来存放它,因为托管字节[]被传递,意味着数组周围有数据,但是断言相同的数据适合托管的double []是最多可疑的,但大多数可能是错误的,并且改变数据以使其适用于托管双[]是邪恶的。

[编辑]

看起来Marshal.Copy是去这里的路。创建一个新的阵列,让元帅复制它们(希望他会快于我,或者,也许在以后的日子,他会更快):

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

其中一个关键的事情需要注意有关已发布的代码是,有没有办法知道有多少项目是返回值被指出和管理的阵列需要知道如何它是大的。您可以返回double*或创建new double[XXX]并复制这些值,或者甚至(如果计数不变)使用public fixed double _data[2];成员创建struct,并将原始数据转换为该类型。

+0

这基本上就是我最终做的。我创建了一个固定长度的double数组,然后一次一个地复制我的值。以C++的方式,不会分配新的double数组会很好。是的,一个double []和byte []被设置为与al,ax和eax寄存器重叠的结构,但是创建一个结构的开销可能超过我正在做的事情......这可能会让你想想,为什么你要在你的数组复制中如此复杂?我回答“”。 – 2009-12-17 16:53:43