Pour l'apprentissage j'ai récemment regardé un assembly existant (en utilisant Reflector) qui utilise Win32 WriteFile. La mise en œuvre est:arithmétique de pointeur et le compilateur C#
Write(IntPtr handleFile, void* bufferData, uint length){
void* buffer = bufferData
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, buffer, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
// This does not compile, because of the cast but also simply because void* does not have += operators (it is unknown size).
buffer += (void*)wrtn;
len -= wrtn;
}
}
Il est en fait les 2 dernières lignes qui sont problématiques ... Pour un, le compilateur se plaint que vous ne pouvez pas lancer uint d'annuler *. De plus, il n'est tout simplement pas possible d'utiliser + = ou même + sur void * car il n'est pas de taille connue.
Write(IntPtr handleFile, void* bufferData, uint length){
byte* buffer = (byte*)bufferData
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, (void*)buffer, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
// This works! I can add to a byte*
buffer = buffer + wrtn; // I could also have used buffer += wrtn
len -= wrtn;
}
}
Le code ci-dessus fonctionne, mais encore les dernières lignes compilera à:
buffer += (byte*)wrtn;
Je ne comprends pas pourquoi et voudrais bien savoir pourquoi le compilateur se comporte de cette façon:
Pourquoi génère-t-il la distribution comme ceci (et pourquoi n'est-il pas accepté de le faire dans le code écrit par l'utilisateur)?- Qu'est-ce qui se passe avec les opérateurs + = sur void * dans le premier exemple? Quel code de code original a généré buffer + = (void *) wrtn où buffer est également vide * ????
Merci pour la réponse, mais comme je l'ai déjà signalé dans mon article original, je connais l'ensemble de la taille "inconnue". Ce qui me surprend, c'est que le compilateur génère en quelque sorte void * somepointer + = (void *) uint wrtn (j'ai ajouté le type pour plus de clarté). Cela ne devrait pas être possible (et ne compile certainement pas!) Alors je me demande quel était le code original qui a généré ceci ... – Kris
Donc c'est très probablement une chose de Reflector.Après tout, la tâche des réflecteurs n'est probablement pas facile. Je pourrais comprendre comment le réflecteur recrache les moulages en fonction de l'IL qu'il trouve, donc cette partie de la question que je considère résolue. Cependant, j'ai essayé et essayé de générer une sortie de réflecteur (pour avoir un aperçu) exactement comme dans mon tout premier bloc de code (donc sans utilisation de byte *) et je ne peux pas y arriver ... Vous ne pouvez pas faire beaucoup avec void * donc je suis vraiment curieux de savoir à quoi ressemblerait le code original qui a généré ça! – Kris
Très certainement, il ressemblait à votre copie «fixe» (dans une certaine tolérance). Avez-vous essayé de jeter l'IL et de le trier manuellement? Il n'est pas difficile de voir avec quoi Reflector doit travailler pour que vous puissiez voir d'où viennent les inférences. –