Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a managed class ASwHTTPMgr and an unmanaged class ASwHTTPMgrCpp. I want to get the instanse of the ASwHTTPMgr and convert it into unmanaged void* and construct the ASwHTTPMgrCpp.
I have an extern C function "platformHTTPwifiNetworkAvailable(void* userData)" defined in the classes and implemented as below.
In that function I want to unwrap the void* and convert it back to the ASwHTTPMgr.
The ASwHttpMgrCpp->wifiNetworkAvailable()function is called at several places in the program.
At the first call platformHTTPwifiNetworkAvailable(), I could see valid data in userData and I could convert it back to managed ASwHTTPMgr without any issues. But the next call to it, I could see the same valid address for the userData, but h.Target is invalid and the call fails. It seems like the pointer got garbage collected at some point.
How could I fix this. Please help.


C#
//////////ASwHTTPMgr.cpp////////////
...
extern "C" {
    bool platformHTTPwifiNetworkAvailable(void* userData) {
	ASwHTTPMgr^ mgr = nullptr;
	Object ^obj = nullptr;
	GCHandle h = GCHandle::FromIntPtr(IntPtr(safe_cast<IntPtr>(userData))); 
	try { 
		obj = safe_cast<Object^>(h.Target); 
		if(obj->GetType() == ASwHTTPMgr::typeid)
		{
		   mgr = safe_cast<ASwHTTPMgr^>(obj);
		   return mgr->wifiNetworkAvailable();   
		}			
	} 
	finally { 				
	    h.Free();
	} 			              
}
.........
ASwHTTPMgr::ASwHTTPMgr()
{
      ASwHTTPMgr^ reftype = this;
      void* opaqueObj = GCHandle::ToIntPtr(GCHandle::Alloc(reftype)).ToPointer();
      _httpMgrCpp = new ASwHttpMgrCpp(opaqueObj);
          
}
//////////////////////////////////////
definition of _httpMgrCpp is

static ASwHttpMgrCpp* _httpMgrCpp;

-----------------------------------------------------------------------------------
//////////////ASwHttpMgrCpp.cpp//////////////////
extern "C" {
    extern bool platformHTTPwifiNetworkAvailable(void* userData);    
}
ASwHttpMgrCpp::ASwHttpMgrCpp(void* userData){
    mUserData = userData;
}
bool ASwHttpMgrCpp::wifiNetworkAvailable() {
	return platformHTTPwifiNetworkAvailable(mUserData);
}
/////////////////////////////////////////////////////
mUserData is defined as
protected:
    void* mUserData;



Thanks.
Posted
Comments
Philippe Mori 5-Jan-12 21:03pm    
A part from the handle you make in the constructor to the managed type, do you have any handle to that type elsewhere to ensure is stay alive or are you pinning the object so it don't get moved/garbage collected.
BoomiJ 6-Jan-12 12:29pm    
Thanks for your reply! I will try you solution below. Is there a way to pin the whole object. How can I do that?

1 solution

Create an unmanaged class that contains the manged class as a member (using gcroot<> for the iomplementation) and then pass that unmanaged class as the user data.

Ensure that the unmanaged class stay alive at least as long as you need to access user data.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900