이 가능한 변환하는 C#double[,,]배열을 double[]없이 복사본을 만들기

StackOverflow https://stackoverflow.com/questions/96054

  •  01-07-2019
  •  | 
  •  

문제

나는 거대한 3 차원 어레이의 숫자에.인터넷 응용 프로그램.내가 변환이 필요하 1D 배열을 전달하 COM 라이브러리입니다.는 방법이 있을 배열 변환없이 모든 데이터의 복사본?

내가 할 수 있는 변환 다음과 같이지만,그때 나는 두번 사용하의 금액을 메모리에서 문제 내용:

  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;
도움이 되었습니까?

해결책

내가 믿지 않는 방식 C#저장된 데이터를 메모리에 만들 것입 가능 같은 방법으로는 간단한 캐스팅에서는 C 것입니다.왜 사용하지 1d 배열로 시작하고,아마도 클래스를 만들 형식에 대한 액세스할 수 있도록 귀하의 프로그램으로 그것이 있다면 3 차원 배열?

다른 팁

불행하게도,C#배열되지 않을 보장하에서 연속적인 메모리처럼 그들이에 더 가까이하 금속 언어 C.그래서,아니다.방법은 없을 변환 double[,,]을 double[]없이는 요소에 의해 요소 복사합니다.

고려한 추상화 데이터 액세스와 함께 프록시 (유사한 반복기/스마트 포인터에서는 C++).불행하게도,구문을하지 않으로 깨끗한 C++로 operator()에 사용할 수 없 과부하고 연산자[]단 arg 지만,여전히 가깝습니다.

물론 이분의 추상화 수준을 추가 복잡성과 작업의 그것의 자신의,하지만 그것을 만들 수 있도록 최소한의 변화를 사용하는 기존 코드 더블[,,]체하는 동안 사용할 수 있도록 하나 double[]배열에 대한 모두 interop 고서-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()
}

다음 사용하는 이 형식을 모두 읽고 쓸'foo[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;
    }
}

다시 추가 개발 비용을 절감하지만,공유 데이터 제거,복사 오버헤드와 복사하는 관련 developtment 비용.그것은 단점.

이를 해결하기 위한 다른 방법은 수준을 유지하는 배열에서 한 차원 형태(어쩌면 가까이에 베어메탈 양식을 전달할 수 있도록 그것은 쉽게 COM 라이브러리?) 고 그런 다음 운영자 과부하[]에 이 클래스를 사용할 수 있도록 다차원에서 배열 C#코드입니다.

없이의 세부 사항을 알고 COM 라이브러리,나는 모양으로 만들기관 클래스에서.물 및 노출 COM,필요한 경우입니다.
귀하의 외관을 더블[,,]고 있는 인덱서는 지도에서[]를[,,].

편집:나는에 대해 동의 점에서 의견,Lorens 제안은 더 낫습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top