注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C#调用C++DLL的小总结6---C++Dll中指针的释放问题  

2013-05-10 15:47:19|  分类: NET(C#) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

C#调用C++DLL的小总结6---C++Dll中指针的释放问题

在平常使用C++的过程中,对指针的操作是谨慎而又谨慎,但这次在C#调用C++DLL时,却又翻了船。

问题是这样的,DLL提供了一个错误获得的函数,GetCurError,它返回一个const char*,最初直接用string封装了,但在本机测试和下断点时,都可以得到数据,但打包后就直接崩溃。当时进度催着,也没有认真去看,直觉上应该是非常指针或者指针被释放掉了。

后来又做一个类似的程序,为了简单,直接开了一个全局的BUF数组,没有产生崩溃的现象。也就没有注意。

这两天又写一个类似的程序,又是获得ERROR,这次是下断点都不可以得到数据,

既然怀疑是指针被释放了,那么就在返回时候儿直接把指针指向的数据复制走不就可以了么?好,C#提供了类似的函数:

Marshal.PtrToStringAnsi(IntPtr)

MSDN上说:将非托管 ANSI 字符串中第一个 null 字符之前的所有字符复制到托管 String,并将每个 ANSI 字符扩展为 Unicode 字符

这下应该好了吧。结果,还是不行。

干脆怀疑是不是C++中的错误机制根本没有起作用,于是下断点跟进去,结果发现,人家得到数据了,然后,然后,没有然后了。

应该是这个类对象在返回时,就直接释放掉了,而且释放的很干脆,很利落,原来是想到这个了,但在C++中编程的经验是,在函数的返回一刻,内存中指针的数据还是存在的(没有覆盖),既然拷走了,再释放就不再乎了,但托管平台调用非托管平台,可能DLL的释放机制有所不同。

这时,忽然想起同事遇到的一个问题,与这个类似,但他的是初始化的过程中,全局变量不知道哪个先初始化(程序异常),当然也遇到了释放时哪个先释放的问题。

以前在多线程里,经常遇到这种问题,警惕性非常高,但在跨平台DLL中还是第一次遇到这种问题,没有引起注意。问题既然找到了,解决就好说,一个是分配内在空间,然后自己控制释放,另外一种仍然使用全局的BUF数组。

下来进行了测试,果然,直接返回字符串如“abcd”和返回s,char s[]=”abcd”,程序都不报错,数据也对,但后者会有一个警告。

就是说返回了一个临时变量的指针,但由于这个在栈上的数据没有被覆盖,所以仍然可以得到正确的数据,而直接返回字符串实际上是返回一个字符串常量,其是分配在特定的全局区域的,所以不会报错。

这里的getcurerror函数中,使用的是一个封装好的类,类变量在退出函数时,即被销毁,调用析构函数将其内容清除,所以才报错。与前面的普通的字符指针函数返回要区别开来

由此想到昨天一兄弟说用CString.Format这个函数,先是int,后是string时,就报错,得不到正常结果,反过来就正常,这明显不可能。结果后来发现,不是int,int64。所以这些都与内存有关系,因此在操作内在时,一定要慎之又慎,不可以掉以轻心。

知行并举,方是正道。

  评论这张
 
阅读(1062)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017