将托管类型转换为void *并返回 [英] converting managed type to void* and back

查看:91
本文介绍了将托管类型转换为void *并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个托管类ASwHTTPMgr和一个非托管类ASwHTTPMgrCpp.我想获取ASwHTTPMgr的实例并将其转换为非托管void *并构造ASwHTTPMgrCpp.
我在类中定义了一个外部C函数"platformHTTPwifiNetworkAvailable(void * userData)",并如下实现.
在该函数中,我想解开void *并将其转换回ASwHTTPMgr.
在程序中的多个位置调用ASwHttpMgrCpp-> wifiNetworkAvailable()函数.
在第一个呼叫平台HTTPwifiNetworkAvailable()上,我可以在userData中看到有效的数据,并且可以将其转换回托管的ASwHTTPMgr,而不会出现任何问题.但是下一次调用它,我可以看到userData的有效地址相同,但是h.Target无效,调用失败.似乎指针在某个时刻被垃圾收集了.
我该如何解决.请帮忙.


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.


//////////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.

推荐答案

创建一个包含托管类作为成员的非托管类(使用gcroot<>作为实现),然后将该非托管类作为用户数据传递.

确保非托管类至少在您需要访问用户数据时才保持活动状态.
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.


这篇关于将托管类型转换为void *并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆