Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / March 2008

Tip: Looking for answers? Try searching our database.

Converting System.Object^ to void*

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Dilip - 29 Feb 2008 16:53 GMT
What is the best way to get a void* out of System.Object^?

Right now this is the way we go:

MyRefClass^ myreftype = ; // from somewhere
void* opaqueObj =
GCHandle::ToIntPtr(GCHandle::Alloc(myreftype)).ToPointer();

when we unpack:

void* p = //........
GCHandle ourWrapper = GCHandle::FromIntPtr(safe_cast<IntPtr>(p));
MyRefClass^ ourObject = ourWrapper.Target;

I am wondering if I can eliminate GCHandle from the picture and get to
what I want?  There is a deeper problem w.r.t passing GCHandle between
appdomains and I was wondering if there is a simple out of this mess.
Tamas Demjen - 29 Feb 2008 18:06 GMT
> What is the best way to get a void* out of System.Object^?

For what reason? If you need to pass the address of a managed object to
unmanaged code, you must pin it.

You can use pin_ptr<>, or if it's absolutely necessary,
GCHandle::Allocate with GCHandleType::Pinned passed to it.

If you don't pin the object, its address is free to change at any moment.

Tom
Dilip - 29 Feb 2008 22:46 GMT
> > What is the best way to get a void* out of System.Object^?
>
> For what reason? If you need to pass the address of a managed object to
> unmanaged code, you must pin it.

Tamas, I suspected that I would have to pin it.  In my case I have
some code (lets call it 'rude_code' so that I can refer back to it
later) running on a secondary (non-default) appdomain that registers a
callback with unmanaged code.  While registering the callback we have
to pass in the address of a managed object as a void*.  When the
callback happens I get back the same void* which I have to break apart
and retrieve the System.Object^ type.  When I have a GCHandle one of
the steps involved in breaking apart a void* is calling
GCHandle::FromIntPtr().

However the problem is I get a "GCHandle cannot be passed across
appdomains" exception on the FromIntPtr call, whenever rude_code is
made to run on the secondary appdomain.  If I run rude_code in the
default appdomain everything works just fine!

Thats why I thought I'd circumvent the issue by not using a GCHandle
at all while converting a System.Object^ to a void* and still be able
to run rude_code in a secondary appdomain.

At this point my questions are mostly academic since I was forced to
back out this dual appdomain approach for lack of time but I am still
curious to know why I got that exception.

When unmanaged code calls back into managed code doesn't it know which
appdomain to select to execute?
Jeroen Mostert - 29 Feb 2008 23:07 GMT
>>> What is the best way to get a void* out of System.Object^?
>> For what reason? If you need to pass the address of a managed object to
[quoted text clipped - 18 lines]
> at all while converting a System.Object^ to a void* and still be able
> to run rude_code in a secondary appdomain.

That will not work. You *must* either allocate a GCHandle or pin the object,
otherwise the object is eligible for garbage collection.

You can't really "convert" a managed reference to an unmanaged pointer. You
can only temporarily create unmanaged pointers to managed objects.

> At this point my questions are mostly academic since I was forced to
> back out this dual appdomain approach for lack of time but I am still
> curious to know why I got that exception.
>
> When unmanaged code calls back into managed code doesn't it know which
> appdomain to select to execute?

In general, no, it doesn't -- you must use delegates for that. See
http://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/

Signature

J.

Dilip - 01 Mar 2008 02:41 GMT
> > Thats why I thought I'd circumvent the issue by not using a GCHandle
> > at all while converting a System.Object^ to a void* and still be able
> > to run rude_code in a secondary appdomain.
>
> That will not work. You *must* either allocate a GCHandle or pin the object,
> otherwise the object is eligible for garbage collection.

Gotcha Jeroen.  I understand perfectly.  FWIW, the code I inherited
just allocates a GCHandle and never pins it (using that Pinned
enumeration Tamas was talking about elsethread).  I wonder how it has
been working all these years.

> You can't really "convert" a managed reference to an unmanaged pointer. You
> can only temporarily create unmanaged pointers to managed objects.
[quoted text clipped - 7 lines]
>
> In general, no, it doesn't -- you must use delegates for that. Seehttp://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/

Wow!  Thats *exactly* what I ran into.  Thanks Jeroen!  How in the
world do you guys keep track of things like this??!!  Seems like an
obscure problem to me...
Jeroen Mostert - 01 Mar 2008 10:46 GMT
>>> Thats why I thought I'd circumvent the issue by not using a GCHandle
>>> at all while converting a System.Object^ to a void* and still be able
[quoted text clipped - 6 lines]
> enumeration Tamas was talking about elsethread).  I wonder how it has
> been working all these years.

Allocating a GCHandle will prevent GC as well. Pinning is only necessary if
you need the address of the object in unmanaged code. The code fragment you
showed doesn't: it actually retrieves opaque handles when it calls
.ToIntPtr(), not direct pointers. These handles can be converted back and
passed to managed code for as long as the GCHandle remains allocated.

> Wow!  Thats *exactly* what I ran into.  Thanks Jeroen!  How in the
> world do you guys keep track of things like this??!!  Seems like an
> obscure problem to me...

I didn't keep track; I've never seen this problem before (I've worked with
callbacks into unmanaged code and separate appdomains, just not in
combination). I simply googled for "delegate unmanaged appdomain". The
supplied site is the first hit. Knowing that delegates should probably be
involved is a guess, granted.

Now that I have seen it, however, I will keep track, in case anyone around
me ever runs into it. Repeat until all-knowing! :-)

Signature

J.


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.