|
|
||||||
|
#1
|
|
|
|
|
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)).ToP ointer(); 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. |
|
|
|
#2
|
|
|
|
|
Dilip wrote:
> 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 |
|
#3
|
|
|
|
|
On Feb 29, 12:06 pm, Tamas Demjen <tdem> wrote:
> Dilip wrote: > > 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? |
|
#4
|
|
|
|
|
Dilip wrote:
[..] > > 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. > 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/un...main-callback/ |
|
#5
|
|
|
|
|
On Feb 29, 5:07 pm, Jeroen Mostert <jmost> wrote:
> Dilip wrote: > > 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. > > > 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. 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... |
|
#6
|
|
|
|
|
Dilip wrote:
> On Feb 29, 5:07 pm, Jeroen Mostert <jmost> wrote: >> Dilip wrote: >>> 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. > 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! :-) |
|
|
| Similar Threads | |
| How to convert System::String* (or System::Void) to void** in MC++? Hy! I have written a MC++ wrapper DLL file for use in a C# project. This wrapper DLL is built on a C DLL. I have the following functions in the C DLL: int First(char* a1,... |
|
| Convert void pointer to System.Object Hopefully someone can help me out with this; if what I'm asking is even possible. My basic question is how can I convert a void * into an Object and then later convert it... |
|
| Converting a BSTR to System::Object, How??? Hi I am using mixed mode C++ and I wonder.... How could I convert a BSTR to a System::Object* type Cheers, |
|
| Method not found: Void System.EventHandler..ctor(System.Object, IntPtr). Hi! While trying to run my first web application using Microsost Visual Studio .net I came up with the following error: Method not found: Void... |
|
|
All times are GMT. The time now is 07:04 PM. | Privacy Policy
|