También puede usar una matriz de bytes para esto.
Esto se hace mediante el uso de una rutina insegura y el estado fijo:
static unsafe void PerformOperation()
{
byte[] buf = new byte[1024];
fixed (void* ptr = &buf[0])
{
SomeUnmanagedFunction(new IntPtr(ptr));
}
}
La cuestión - y esto es una muy importante - es que SomeUnmanagedFunction no se le permite tocar ese puntero después de que haya regresado y el código ha salido del bloque fijo. Entonces, si usted hace algo como esto:
static void PerformFabulousTrick()
{
byte[] buf = new byte[1024];
fixed (void *ptr = &buf[0])
{
SetBuffer(ptr, buf.Length);
}
FillBuffer(); // puts data in buf - NOT - may crash hard
}
usted está pidiendo nada más que problemas. En este caso, probablemente desee utilizar un GCHandle, que puede fijar un objeto administrado en el montón. Esto también puede ser problemático, ya que NECESITA destrabarlo de manera oportuna o corre el riesgo de fragmentar su pila.
En general, recomendaría asegurarse de que está P/Invocando correctamente en la función para que el tal Marshall pueda hacer este trabajo por usted. Me gusta mejor que Fix GlobalAlloc porque su alcance es claro. No puedo decidir cuál me gusta menos de GlobalAlloc y GCHandle. Ambos requieren para realizar más trabajo ya que el GC o el idioma no lo harán por usted.
¿Qué pasa con 'new byte [1024]'? –
@ John Saunders: No sé si eso sería confiable ya que no se garantiza que la memoria administrada sea contigua. También es probable que desee fijarlo para evitar que el GC lo mueva mientras lo estaba utilizando. – Joshua
@Joshua Huh? La memoria administrada está garantizada que es contigua. No está garantizado que permanezca en el mismo lugar, pero cuando lo hace, es contiguo, y hay 'fijo 'para mantenerlo estable. –