Tuesday, March 13, 2007

dynamic blocks of unmanaged memory in XNA

In XNA, a problem ive found with using structs instead of classes is that in order to have referances you need pointers, and pointers are really annoying and impractical to use in managed code.
So how can you get unmanaged blocks of memory?

Stackalloc: this only works if you need a block on the stack, and is useless if you want to keep the memory to use throughout the life of your game.

Heapalloc: this is a good choice if you are writing a game for windows, but the .net compact framework does not offer this interop service, so it is not possible if you want your game to work on xbox 360.

the GCHandle struct: this is the only way I have found to do it. A GCHandle is a struct which holds the address,size and type of a block of Managed memory. You might be thinking, "What is the use of a handle to managed memory? I thought we want unmanaged memory so we can use pointers in it?" Technically it is managed, but in all practical sense it can be "unmanaged" by getting the handle using GCHandleType.Pinned. With an address to pinned memory, you can use pointers all you like and know that what you expect to be there will actualy be there.

here is how you would get the handle to a block of memory:
MY_STRUCT[] mybuffer;
mybuffer = new MY_STRUCT[100];
GCHandle pinbuffer = GCHandle.Alloc(mybuffer,GCHandleType.Pinned)


here is how you would get a pointer to use in your buffer:
MY_STRUCT* mypointer = (MY_STRUCT*)pinbuffer.AddrOfPinnedObject().ToInt32();
now you can use that pointer all you like,or you can cast it into different pointers, or you can do whatever, just dont overrun the buffer.

you must explicitly free your memory like this:
pinbuffer.Free();


Lastly, I am still a newbie at managed programming, so if anythign I said is incorrect I opologize. Though this method has worked very well for me, and on critical areas I get a nice performance boost by using structs and pointers instead of classes and class referances.
Not to mention it feels more like home.

No comments: