2009-12-07 5 views
3

j'ai un réseau multidimensionnel de pointeurs vers entier (de rang inconnu) étant passé dans mes fonctions en tant que tel:valeur de réglage de manière dynamique sur tableau de pointeurs vers des nombres entiers

public unsafe static void MyMethod(Array source, ...) 
    { 
     //... 
    } 

tableaux multidimensionnels de pointeurs sont construits à l'extérieur de la méthode et étant passé dans Voici un exemple:.

int*[,,,] testArray = new int*[10,10,5,5]; 

MyMethod(testArray); 

Comment puis-je définir une valeur à un indice calculé d'exécution dans le tableau? Array.SetValue (...) fonctionne parfaitement pour les tableaux sans pointeur, mais refuse de fonctionner pour mon tableau int *. En utilisant le réflecteur, je vois SetValue se réduit à appeler InternalSetValue qui prend un objet pour la valeur mais il est marqué comme extern et je ne peux pas voir l'implémentation. J'ai pris une photo dans le noir et j'ai essayé de passer dans un encadré, mais pas de chance.

Répondre

4

Cela fonctionne:

unsafe static void MyMethod(int** array) 
{ 
    array[10] = (int*)0xdeadbeef; 
} 

private static unsafe void Main() 
{ 
    int*[, , ,] array = new int*[10, 10, 10, 10]; 

    fixed (int** ptr = array) 
    { 
     MyMethod(ptr); 
    } 

    int* x = array[0, 0, 1, 0]; // == 0xdeadbeef 
} 

Est-ce que l'aide?


Question aux experts: Est-il erroné de supposer que le tableau est alloué consécutivement dans la mémoire?

+0

Non, ce n'est pas faux. Les tableaux sont alloués consécutivement. –

+0

@Maximilian: Merci. Est-ce documenté quelque part? Ou est-ce un détail de mise en œuvre si le CLR? – dtb

+3

Oui, ceci est spécifié par Ecma-335 (spécification CLI): "Les éléments du tableau doivent être disposés dans l'ordre du rang principal (les éléments associés à la dimension du tableau le plus à droite __sont disposés de manière contiguë au plus haut indice). " –

1

Cela ne fonctionne pas car il n'est pas possible d'encadrer un pointeur dans .NET, donc vous ne pouvez jamais appeler le Array.SetValue et passer un int*. Pouvez-vous déclarer MyMethod pour accepter int*[,,,] à la place?

Modifier: pour plus d'informations, an interesting recent post from Eric Lippert.

+0

L'exigence de la méthode est qu'elle fonctionne avec un tableau de n'importe quelle dimension. En outre, voir: http://msdn.microsoft.com/en-us/library/system.reflection.pointer.box.aspx –

+0

OK, mais Array.SetValue ne sait pas comment décocher un pointeur encadré à l'aide de Pointer.Box : Je reçois "System.NotSupportedException: Type n'est pas pris en charge." –

+0

Je l'ai trouvé (voir ci-dessus) - C'est en fait Array.InternalGetReference (aussi marqué comme extern) en lançant cette exception. –

Questions connexes