2008-09-18 77 views
5

我的.NET应用程序中有庞大的3D数组数组。我需要将它们转换为一维数组以将其传递给COM库。有没有办法转换数组而不复制所有数据?是否可以将C#double [,,]数组转换为double []而不创建副本

我可以做这样的转换,但后来我使用的内存ammount的两倍这是在我的应用程序的问题:

double[] result = new double[input.GetLength(0) * input.GetLength(1) * input.GetLength(2)]; 
    for (i = 0; i < input.GetLength(0); i++) 
    for (j = 0; j < input.GetLength(1); j++) 
     for (k = 0; k < input.GetLength(2); k++) 
     result[i * input.GetLength(1) * input.GetLength(2) + j * input.GetLength(2) + k)] = input[i,j,l]; 
    return result; 

回答

8

我不相信的样子C#存储在内存中的数据会使其可行以同样的方式在C简单的铸件会。为什么不使用1d数组开始,并且可能为该类型创建一个类,以便可以在程序中访问它,就好像它是3d数组一样?

6

不幸的是,C#数组不能保证像连续内存他们更接近金属语言,比如C。所以,不。如果没有逐个元素的副本,无法将double [,,]转换为double []。

1

不知道你的COM库的细节,我会考虑在.NET中创建一个门面类,它,暴露在COM如果必要的。
你的外观需要一个双[],并有一个索引器,将从[]到[,,]映射。

编辑:我同意在评论中提出的观点,小嘴等着建议是更好的。

+0

这不起作用。 COM将**需要**具有文字double []数组。如果有的话,你会想创建一个.NET类,使双[]行为像双[],。 – 2008-09-18 19:36:37

1

作为一种变通方法,你可以使其保持在一种维形式的阵列的一类(甚至在更靠近裸金属的形式,从而可以很容易地将它传递给COM库?),然后在这个类重载operator []以使其可用作C#代码中的多维数组。

3

考虑一个具有Proxy(类似于迭代器/智能指针在C++)抽象访问数据。不幸的是,语法并不像C++那么干净,因为operator()不能用于重载,而operator []是单精度的,但仍然很接近。

当然,这种额外的抽象层次增加了其自身的复杂性和工作量,但它可以让您对使用double [,,]对象的现有代码进行微小的更改,同时允许您使用单个double [ ]数组,用于interop和您的in-C#计算。

class Matrix3 
{ 
    // referece-to-element object 
    public struct Matrix3Elem{ 
     private Matrix3Impl impl; 
     private uint dim0, dim1, dim2; 
     // other constructors 
     Matrix3Elem(Matrix3Impl impl_, uint dim0_, uint dim1_, uint dim2_) { 
      impl = impl_; dim0 = dim0_; dim1 = dim1_; dim2 = dim2_; 
     } 
     public double Value{ 
      get { return impl.GetAt(dim0,dim1,dim2); } 
      set { impl.SetAt(dim0, dim1, dim2, value); } 
     } 
    } 

    // implementation object 
    internal class Matrix3Impl 
    { 
     private double[] data; 
     uint dsize0, dsize1, dsize2; // dimension sizes 
     // .. Resize() 
     public double GetAt(uint dim0, uint dim1, uint dim2) { 
      // .. check bounds 
      return data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ]; 
     } 
     public void SetAt(uint dim0, uint dim1, uint dim2, double value) { 
      // .. check bounds 
      data[ (dim2 * dsize1 + dim1) * dsize0 + dim0 ] = value; 
     } 
    } 

    private Matrix3Impl impl; 

    public Matrix3Elem Elem(uint dim0, uint dim1, uint dim2){ 
     return new Matrix2Elem(dim0, dim1, dim2); 
    } 
    // .. Resize 
    // .. GetLength0(), GetLength1(), GetLength1() 
} 

,然后使用这种类型来读取和写入 - “富[1,2,3]”现在写为“foo.Elem(1,2,3)。价值”,在这两个读取值和写入值,分配和值表达式的左侧。

void normalize(Matrix3 m){ 

    double s = 0; 
    for (i = 0; i < input.GetLength0; i++)  
     for (j = 0; j < input.GetLength(1); j++)  
      for (k = 0; k < input.GetLength(2); k++) 
    { 
     s += m.Elem(i,j,k).Value; 
    } 
    for (i = 0; i < input.GetLength0; i++)  
     for (j = 0; j < input.GetLength(1); j++)  
      for (k = 0; k < input.GetLength(2); k++) 
    { 
     m.Elem(i,j,k).Value /= s; 
    } 
} 

同样,增加开发成本,但共享数据,消除复制开销并复制相关的开发成本。这是一个折衷。

相关问题