2009-12-16 12 views
7

J'essaie de créer une matrice gérée de doubles à partir d'un tableau d'octets. J'ai le problème de travailler actuellement, mais je voulais optimiser. Voici un code que je voudrais travailler:C# - Créer une matrice gérée à partir d'un pointeur

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

S'il vous plaît laissez-moi savoir comment faire face à ces problèmes.

-Aaron

+0

En général lorsqu'ils traitent avec Interop, le Marshaller est votre ami, à votre service à System.Runtime.InteropServices.Marshal. Je ne sais pas exactement ce dont vous avez besoin pour utiliser des tableaux. Vous pouvez cependant accéder à des tableaux avec un arithmétique de pointeur. Peut-être que cela vous indique la bonne direction. – OregonGhost

+0

@daGhost - Je suis certainement conscient d'avoir accès à des tableaux avec des pointeurs, mais je devrai m'intéresser à la mise en place d'un tableau géré. Merci. –

+0

@Limited Thing (Veuillez ne plus m'appeler daGhost): Si vous pouvez accéder aux éléments du tableau avec des pointeurs, vous pouvez copier les valeurs dans un tableau géré. – OregonGhost

Répondre

2

Tout à l'heure, je pensais que stackalloc serait le bon chemin, mais il échoue. Plus important encore, je sais maintenant qu'il était voué à l'échec. Il n'y a aucun moyen de faire ce que je veux faire.

Cela peut être vu en reformulant la question:

Comment puis-je créer un tableau managé autour d'un tableau « dangereux »?

Étant donné qu'un tableau géré possède des informations d'en-tête (car il s'agit d'une classe autour d'un mandrin de mémoire), il requiert plus d'espace en mémoire que le tableau lui-même. Donc, la réponse est:

Allouer de l'espace avant (et/ou après - selon la façon dont les tableaux gérés sont stockés en mémoire) le tableau lui-même et mettre les informations gérées (longueur, (et cetera)) autour du 'tableau.

Cela n'est pas facile car il est difficile de garantir que les données sont suffisantes autour de la matrice. Dans mon exemple particulier, il peut y avoir assez d'espace car un octet géré [] est passé en signifiant qu'il y a des données autour du tableau, mais affirmer que les mêmes données sont appropriées pour le double géré est douteux, mais la plupart probablement erroné, et changer les données pour le rendre approprié pour le double géré [] est néfaste.

[EDIT]

Il ressemble à Marshal.Copy est la voie à suivre ici. Créer un nouveau tableau et laisser le maréchal les copier (en espérant qu'il sera plus rapide que moi, ou peut-être à une date ultérieure, il sera plus rapide):

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

L'une des choses importantes à noter à propos du code que vous avez posté est qu'il n'y a aucun moyen de savoir combien d'articles sont pointés par la valeur de retour, et un tableau managé a besoin de savoir comment c'est grand. Vous pouvez renvoyer un double* ou créer un new double[XXX] et copier les valeurs ou même (si le nombre est constant) créer un struct avec un membre public fixed double _data[2]; et diffuser les données brutes à ce type.

+0

C'est essentiellement ce que j'ai fini par faire. J'ai créé le double tableau avec une longueur fixe, puis copié mes valeurs là-bas un à la fois. Ce serait sympa de ne pas allouer le nouveau double tableau en C++. Ouais, une structure avec un double [] et un octet [] pour chevaucher comme les registres al, ax, et eax, mais le temps de création d'une structure pourrait être plus que ce que je fais ... ce qui pourrait vous rendre Pensez, pourquoi diable voudriez-vous être si alambiqué dans votre tableau-copie? A quoi je réponds ". –