GCHandle question

Posted on 2005-04-14
Last Modified: 2012-08-14
I have the following :

int MyInt = 100;

GCHandle gch = GCHandle.Alloc( MyInt, GCHandleType.Pinned );

If i print GCHandle.Target i get 100. Now, if i do :

Myint = 200;

And i print GCHandle.Target i still get 100. Is this normal ?
I thought GCHandle gives me a stable pointer to the object (MyInt).
But it seems as if it copies MyInt somewhere and returns a pointer to the copy.

I am calling a function in an unmanaged DLL that requires a pointer to an int.
This pointer must remain stable for the lifetime of my app since it's value is updated
thru other calls to the DLL. This means that I have to do MyInt = GCHandle.Target to
get the new value every time I call a DLL function that modifies the pointer value.

Is this the only way of getting a stable pointer (no GC and no moving) ?

Question by:drinkwater
    LVL 7

    Expert Comment

    The reason your integer gets "copied" somewhere else and then written to is because int is a value type. When you cast a value type to "object," the value gets boxed (that is, copied to a new location on the stack). But don't be discouraged -- once pinned, boxed values *can* be modified, you just have to know how to do it. Here's a sample:

          GCHandle h = GCHandle.Alloc(100, GCHandleType.Pinned);
          Marshal.WriteInt32(h.AddrOfPinnedObject(), 500);

    All that needs to be done differently is using the Marshal class to set the value, because C# doesn't actually have any syntax for doing what you're trying to do. Note also that you can just look at h.Target to get the value, but it's going to be slightly less efficient because under the covers, it will go to the location on the heap where the int was boxed before, pull the integer out, then box it again. Using Marshal.ReadByte() will return the int directly on the stack, avoiding the extra boxing operation.

    Don't forget to Free() the handle when you're done with it (or those four bytes will never be deallocated), and you should be good. Hope this helps.
    LVL 7

    Expert Comment

    Er...the parentheses on "the value gets boxed" should read "that is, copied to a new location on the HEAP," not the stack. Sorry for the confusion.

    Author Comment

    Aha, so that's what boxing is ! My main concern is that the pointer never move or be garbage collected. The Int example is just one case. But I have other cases where I need a pointer to a buffer (again must not move or be GC). If I use Marshal.AllocHGlobal which returns an IntPtr - can I be sure that it will never move or be GC ? Remember I am passing
    the pointer to an unmanaged DLL which stores the pointer and uses that pointer in other calls to the DLL
    LVL 7

    Accepted Solution

    Yes, the pointers returned from AllocHGlobal() are guaranteed to stay in place. Things that you pin by creating a GCHandle are also guaranteed not to be moved out from under you -- which one you use depends on your needs. If all you want is a buffer where managed APIs can store and retrieve data, go ahead and use AllocHGlobal(). If you want an object that can be passed back and forth between managed and unmanaged code and used intuitively in both contexts, use GCHandle. Make sure to remember to call GCHandle.Free() or FreeHGlobal() when you're done with it, though.
    LVL 48

    Expert Comment

    Result of Marshal.AllocHGlobal is pointer to unmanaged memory block which is not subject of garbage collecting and will never be moved.
    IntPtr structure itself, however, can be moved by GC, but it's value remains the same and memory block pointed by it will not be moved.

    Expert Comment

    Hey Ceiled, dont want to highjack a questino, although this one has been answered, and experts-exchange don't have the ideas to put in a request member to view your question button, so I hope you could take a look over at as I have a similar problem using the gchandle, which isn't quite working out...

    Featured Post

    Better Security Awareness With Threat Intelligence

    See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

    Join & Write a Comment

    Introduction                                                 Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.   Also called…
    This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
    To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…
    In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor ( If you're interested in additional methods for monitoring bandwidt…

    732 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    24 Experts available now in Live!

    Get 1:1 Help Now