文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>P/Invoke调用dll函数,将本来void的函数声明为带返回值的,在win7出错,在winxp下正常,理由是?-- 续

P/Invoke调用dll函数,将本来void的函数声明为带返回值的,在win7出错,在winxp下正常,理由是?-- 续

时间:2010-10-20  来源:不及格的程序员-八神

CLR内存管理在平台调用中使用COM内存管理模型,也就是说它会本着"有来有去"或是"从来里来就回哪里去的原则审请或释放内存.

从1993年就随着OLE一起出来的COM编程模型,在目前的CLR中依然有着很重要的地位.

它的内存管理模型,消除了在不同内存堆审请的内存,释放不一至的情况,而如今它也被应用到了CLR的平台调用中.

 

CLR运行库始终使用 CoTaskMemFree 方法来释放来自非托管的内存,所以对于文中使用string做为返回值的函数声明来说.

CLR偿试回收这个内存地址,而实际上这个内存不是使用CoTaskMemAlloc 审请的,所以最终就会出现内存访问异常.

作为替代方案,我们可以将函数声明为返回System.IntPtr指针,这样CLR就不会主动释放这块内存,达到最初的目的.

同时由于以上原因某些函数原型声明在平台调用中是不被支持的,比如: __declspec(dllexport) char* GetChar(char* c) { return c;}

 

补充示例,从非托管函数中返回字符串,注意函数内部使用CoTaskMemAlloc审请内存,调用时CLR会调用CoTaskMemFree函数释放这块内存.

1 extern "C" _declspec(dllexport) char * TestStringAsResult()
2 {
3 STRSAFE_LPWSTR result = (STRSAFE_LPWSTR)CoTaskMemAlloc( 64 );
4 StringCchCopy( result, 64 , (STRSAFE_LPWSTR) "This is return value" );
5 return (char *) result;
6 }

 

 

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载