2010-08-24 7 views
3

Ma méthode non sécuritaire accepte une collection byte[] s. Tous ces byte[] sont de la même taille.Initialiser une collection de byte * en C#

J'ai besoin d'itérer sur eux tous, en recherchant certains modèles. La recherche est intrinsèquement reinterpret-cast style: à chaque offset, je dois considérer une valeur comme si c'était un float, un double, un short, un int, etc. Donc obtenir un byte* pour chaque entrée byte[] et l'incrémenter sur chaque L'itération semble être une approche naturelle.

Malheureusement, je ne trouve aucun moyen de créer une collection de byte* - ou, plus précisément, de l'initialiser à partir d'une collection de tableaux. Des idées?

est ici une version quelque peu artificielle de la tâche:

static unsafe void SearchIteration(List<byte[]> arrays, byte[] resultArr) 
{ 
    fixed (byte* resultFix = resultArr) 
    { 
     byte* resultPtr = resultFix; 
     byte*[] pointers = new byte*[arrays.Count]; 

     <some code to fix all the arrays and store the pointers in "pointers"> 

     int remaining = resultArr.Length; 
     while (remaining > 0) 
     { 
      <look at resultPtr and each of the pointers and update *resultPtr> 

      remaining--; 
      for (int i = 0; i < pointers.Length; i++) 
       pointers[i]++; 
     } 
    } 
} 

Essentiellement, la question est de savoir comment initialiser pointers avec les adresses de arrays, tout en épinglant les tableaux de telle sorte que GC ne les déplace pas.

+0

Quelle est exactement votre collection d'objets, et quels sont dans l'octet []? – Raynos

+0

Avez-vous vraiment besoin d'avoir tous les octets [] dans les tableaux à épingler en même temps, ou pourriez-vous les traiter les uns après les autres? – dtb

+0

@Raynos désolé pour la confusion, j'ai simplifié un peu et j'ai oublié d'enlever une référence à "objets". Parti maintenant. Juste 'byte []' s. –

Répondre

2

utilisation GCHandle.Alloc() de System.Runtime.InteropServices:

var handles = new GCHandle[arrays.Count]; 
byte*[] pointers = new byte*[arrays.Count]; 
for(int i = 0; i < arrays.Count; ++i) 
{ 
    handles[i] = GCHandle.Alloc(arrays[i], GCHandleType.Pinned); 
    pointers[i] = (byte*)handles[i].AddrOfPinnedObject(); 
} 
try 
{ 
    /* process pointers */ 
} 
finally 
{ 
    for(int i = 0; i < arrays.Count; ++i) 
    { 
     handles[i].Free(); 
    } 
} 
+0

Qui épingle les objets. Mais où pointe le pointeur (le contenu du tableau ou l'en-tête de l'objet CLR de l'objet tableau)? – dtb

+0

il pointe à exatly ce que vous attendez - premier élément de tableau – max

+0

Merci max, cela fonctionne. J'ai oublié d'accepter plus tôt. –