Te damos la contestación a este contratiempo, al menos eso creemos. Si sigues con dudas dínoslo y con gusto te ayudaremos
Solución:
La CLI distingue entre punteros administrados y no administrados. Se escribe un puntero administrado, el tiempo de ejecución conoce el tipo del valor apuntado y solo se permiten asignaciones de tipo seguro. Los punteros no administrados solo se pueden usar directamente en un lenguaje que los admita, C++/CLI es el mejor ejemplo.
El equivalente de un puntero no administrado en el lenguaje C# es IntPtr
. Puede convertir libremente un puntero de un lado a otro con un molde. No tiene asociado ningún tipo de puntero a pesar de que su nombre suena como “puntero a int”, es el equivalente de void*
en C/C++. El uso de un puntero de este tipo requiere pinvoke, la clase Marshal o una conversión a un tipo de puntero administrado.
Algo de código para jugar:
using System;
using System.Runtime.InteropServices;
unsafe class Program
static void Main(string[] args)
int variable = 42;
int* p = &variable;
Console.WriteLine(*p);
IntPtr raw = (IntPtr)p;
Marshal.WriteInt32(raw, 666);
p = (int*)raw;
Console.WriteLine(*p);
Console.ReadLine();
Tenga en cuenta cómo el unsafe
la palabra clave es apropiada aquí. Puede llamar a Marshal.WriteInt64() y no recibe ninguna queja. Corrompe el marco de la pila.
Un IntPtr
no se puede utilizar como reemplazo de un puntero.
los IntPtr
solo contiene un valor numérico, por lo que no puede usarlo para acceder a ningún dato. De ahí el nombre; es un valor entero con el mismo tamaño que un puntero. Debe convertir el valor en un puntero para acceder a los datos a los que apunta, por lo que no hay forma de acceder a los datos sin usar un código no seguro.
Tenga en cuenta también que IntPtr
es una estructura, no un objeto, por lo que el recolector de basura no está directamente relacionado con él.
IntPtr
es un objeto administrado, pero el objeto al que apunta aún no se recolecta como basura. El uso de punteros inseguros en C# es realmente algo que debe evitar. Es posible que el código que usa punteros inseguros no tenga en cuenta las diferencias en las direcciones de memoria entre los sistemas x86 y x64. Le permite manipular directamente las direcciones de memoria fácilmente, lo que no es el caso con IntPtr, ya que necesitaría clasificar entre el puntero y la estructura real almacenada en esta dirección de memoria. Con los punteros inseguros, podría trabajar directamente con el tipo subyacente: aquí hay una publicación de blog que escribí que ilustra un posible uso de los punteros inseguros. Otro ejemplo común es la manipulación directa de los píxeles de la imagen.
Recuerda mostrar este tutorial si te ayudó.