2008-09-18 29 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; 
    } 
} 

同樣,增加開發成本,但共享數據,消除複製開銷並複製相關的開發成本。這是一個折衷。

相關問題