2009-12-16 32 views
7

Próbuję utworzyć zarządzaną macierz podwójną z tablicy bajtów. Problem występuje obecnie, ale chciałem zoptymalizować. Oto kod, nad którym chciałabym pracować:C# - Utwórz zarządzaną macierz ze wskaźnika

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

Proszę dać mi znać, jak poradzić sobie z tymi problemami.

-Aaron

+0

Na ogół gdy ma do czynienia z Interop, ruchu naziemnego jest Twoja przyjacielu, do usług w System.Runtime.InteropServices.Marshal. Nie wiem jednak, czego konkretnie potrzebujesz do korzystania z tablic. Możesz jednak uzyskać dostęp do tablic z arytmetyką wskaźnika. Może to wskazuje na właściwy kierunek. – OregonGhost

+0

@daGhost - Z pewnością jestem świadomy dostępu do tablic ze wskaźnikami, ale będę musiał przyjrzeć się zestawianiu zarządzanej tablicy. Dzięki. –

+0

@Limited Thing (Proszę nie nazywać mnie daGhost ponownie): Jeśli możesz uzyskać dostęp do elementów tablicy za pomocą wskaźników, możesz skopiować wartości do zarządzanej tablicy. – OregonGhost

Odpowiedz

2

Właśnie teraz pomyślałem, że stackalloc będzie właściwą drogą, ale zawiedzie. Co najważniejsze, teraz wiem, że był skazany na porażkę. Nie ma sposobu, aby zrobić to, co chcę zrobić.

To może być postrzegane przez przekształcenie pytanie:

Jak mogę utworzyć zarządzanego tablicę wokół „niebezpieczny” tablicy?

Ponieważ tablica zarządzana ma informacje nagłówkowe (ponieważ jest to klasa wokół uchwytu pamięci), wymaga więcej miejsca w pamięci niż sama tablica. Tak więc odpowiedź brzmi:

Przydzielanie przestrzeni przed (i/lub po? W zależności od sposobu przechowywania tablic zarządzanych w pamięci) samej tablicy i umieszczanie zarządzanych informacji (długość, (itp.)) Wokół "niebezpiecznych "tablica.

Nie jest to łatwe, ponieważ zagwarantowanie wystarczających danych w całej tablicy jest w najlepszym wypadku niestabilne. W moim szczególnym przykładzie może być wystarczająco dużo miejsca, ponieważ zarządzany bajt [] jest przekazywany w znaczeniu, że istnieją dane wokół tablicy, ale twierdzenie, że te same dane są odpowiednie dla zarządzanego podwójnego [] jest co najmniej wątpliwe, ale większość prawdopodobnie błędne, a zmiana danych, aby była odpowiednia dla zarządzanego podwójnego [], jest nikczemna.

[EDIT]

Wygląda Marshal.Copy jest do zrobienia tutaj. Utworzyć nową tablicę i niech marszałek skopiuj je (w nadziei, że będzie szybciej niż ja, albo, że być może w jakimś późniejszym terminie, będzie szybciej):

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

Jedną z najważniejszych rzeczy do zawiadomienia o kodzie Wysłany jest to, że nie ma sposobu, aby wiedzieć, ile elementy są wskazywane przez wartości zwracanej, a udało tablica musi wiedzieć, w jaki sposób jest duży. Możesz zwrócić wartość double* lub utworzyć new double[XXX] i skopiować wartości, a nawet (jeśli liczba jest stała), utworzyć element struct z elementem public fixed double _data[2]; i przesłać surowe dane do tego typu.

+0

To jest w zasadzie to, co zrobiłem. Stworzyłem podwójną tablicę o stałej długości, a następnie skopiowałem wartości tam jeden po drugim. Byłoby miło, w sposób C++, nie przydzielać nowej podwójnej tablicy. Tak, struktura z podwójnym [] i bajtem [] ustawionym tak, aby zachodziła na siebie jak rejestry al, ax i eax, ale narzut tworzenia struct może być czymś więcej niż to, co robię ... co może sprawić, że pomyśl, dlaczego, na Boga, chciałbyś być tak zawiły w kopiowaniu tablic? Na które odpowiadam ''. –