.NET简谈互操作(四:基础知识之Dispose非托管内存)

互操作系列文章:

  1. .NET简谈互操作(一:开篇介绍)

  2. .NET简谈互操作(二:先睹为快)

  3. .NET简谈互操作(三:基础知识之DllImport特性)

  4. .NET简谈互操作(四:基础知识之Dispose非托管内存)

  5. .NET简谈互操作(五:基础知识之Dynamic平台调用)

  6.  .NET简谈互操作(六:基础知识之提升平台调用性能)

  7. .NET简谈互操作(七:数据封送之介绍)

我们继续.NET互操作学习。前一篇文章中我们学习了基础知识中的DllImport关键特性;我们继续学习基础知识中的内存释放相关技术;

在托管与非托管内存之间,是不允许直接调用进行相互操作的,这点我相信稍微有点.NET技术基础的人都能了解;上一篇文章中有位朋友提出了些问题,刚好我们在这里就当是学习来粗略的分析一下,问题大概是这样的:[王清培版权所有,转载请给出署名]

1.在.NET托管平台上的对象与非托管的对象之间是否能直接互换?

2.托管内存与非托管内存是否存在差异?如果存在差异是否有方法能进行等价转换或者叫做等价复制;

我们就上面两个问题来详细分析一下,由于本人也在学习这方面的知识所以理解的也不是很透彻,只能是一些微薄的猜测吧,大家一起来帮忙分析;

第一个问题:在.NET托管平台上的对象与非托管的对象之间是否能直接互换?其实第一个问题是隐藏在第二个问题里面的,首先我们要确定的是,“互换”与“转换”的概念,为了统一大家步伐,我们必须将“互换”与“转换”做一些定义;

“互换”:我假定有两块内存空间,每块内存空间存储不同的对象,比如:在一块非托管内存块中保存着Char*类型的指针,在另一块托管内存块中保存着String类型的值,由于Char*是指针类型,而我们的托管String是.NET平台类型,微小的变化就可能引起内存布局不同的可能;数据结构里面讲到,变量分为原子型和结构型,原子型变量都存在着字面值的概念,什么叫字面值就是我们人用来交流的数据值,比如:bool类型的true和false;两块内存中保存的东西是不一样的,高级语言在经历了一系列编译器处理之后,会确定下来内存中保存的数据是什么样子的;也就是说内存的分配原则是按照对象的类型来的;在托管与非托管的内存空间中,不同的平台所有的引用地址类型也各不相同,当然如果能成功的“互换”就说明能在托管与非托管之间进行直接数据访问了;总之互换是两个对象之间的彼此转换,是双向的;

“转换”:转换的概念我个人觉得来源于高级语言的语法解释而已,所谓转换其实也就是a到b的转换,将一种类型转换成另一种类型的动词描述,我们具体点打个比方:如果有一个对象是a,有一个对象是b,我想将a转换成b,就是将对象从一种状态转换成另一种状态;总之转换是单向的,只能是一种到另一种的转换;

针对上述我们分析的结果,由于时间比较紧,我们从第二个问题入手吧,因为本篇文章不是解决问题为主的;经过上面的分析我们确定托管内存与非托管内存的结构是不一样的,这种不一样并不是所有的对象类型都不一样,在.NET平台里面有一些如:int,char之类的平台等价类型,是可以直接互换的;如果是一些非等价类型,要想成功进行转换就必须得借助于托管对象关于互操作方面的知识了,由于这样一扯可能今天这篇文章是讲不完了,这里就粗略的过一下吧;我们下面进入今天的主题;其实有些概念真的不太好讲,你要说托管与非托管内存不一样,有人会问不一样在什么地方;真的没有说服性的理由;

关于非托管内存释放的问题

似乎今天的主题就是关于托管与非托管内存的问题,刚好能详细的说明上面的问题;要想在托管内存中释放非托管内存,没有那么简单;不同的代码库,调用的分配内存的方法不一样,算法也就不一样;C的分配与回收是malloc、free,C++的是new、delete,COM是CoTaskMemAlloc、CoTaskMemFree;在操作系统这么大的一个平台上存在着千千万万种内存操作方式,大家所熟悉的是上述几种,有可能那位技术牛人自己写了一套内存分配和回收的DLL,那么我们不可能让.NET一劳永逸,所以存在着这些不确定因素;(我穿插一句废话,其实不管我们所说的底层是什么样子的,哪怕真的越过了内核到了硬件抽象层甚至到了驱动部分,1就是1,2还是2,该走的路程还是会走,我们千万不要神秘话底层,只要我们抱着一颗探索的心什么都OK);:[王清培版权所有,转载请给出署名]

.NET平台的默认内存分配和回收都是基于COM(组件对象模型)的,由于COM是一套非托管年代的公用原则,所以微软只能做到这个位置了;如果非托管内存是用COM的CoTaskMemAlloc分配的那么.NET的封送拆收器会自动的释放掉那块内存;如果是非托管内存是采用C的或者C++或者其他的什么方式分配的.NET根本不知道你是怎么分配的,所以这个时候需要我们采用折中的办法来解决。非托管的内存释放只有非托管知道,所以在非托管中定义一个释放非托管资源的方法,然后在用.NET平台去调用这个非托管方法来进行释放内存;下面我们来看一个小例子,以说明问题为主;

图1:

这是非托管的代码,由于时间关系我就没有写具体的操作了;说明原理就行了;

图2:

这是在托管.NET平台上面定义的非托管代码调用关系;

图3:

这样一来,不管非托管的内存是采用什么方法分配的内存我们都能在托管中将其释放;首要的原则就是我们必须清楚非托管内存的分配方法;如果不清楚的情况下,默认是COM的释放方法;:[王清培版权所有,转载请给出署名]

 

时间: 2024-11-10 07:36:01

.NET简谈互操作(四:基础知识之Dispose非托管内存)的相关文章

.NET简谈互操作(五:基础知识之Dynamic平台调用)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.在上篇文章中我们学习了关于托管与非托管内存Dispose(释放)问题:下面我们继续学习基础知识中的Dyn

.NET简谈互操作(六:基础知识之提升平台调用性能)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.本篇文章我们将来学习互操作基础知识中的最后一个知识点"提升平台调用的性能": 在于非托管函数进

.NET简谈互操作(七:数据封送之介绍)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.互操作的基础知识已经差不多完了,当然一篇小小的文章很难全面的讲述互操作的方方面面,本人只是总结出关键的地

.NET简谈互操作(三:基础知识之DllImport特性)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习,上一篇文章中我们介绍了托管代码怎么与非托管代码C++之间的互操作:要想在托管代码中成功的进行非托管调用,要注意的细

.NET简谈互操作(二:先睹为快)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习,为了揭开互操作的神秘面纱,今天这篇文章我们就来先睹为快,让我们先来做个例子,基础的东西,我们陆续进行讲解:由于互操

.NET简谈互操作(一:开篇介绍)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 本人最近在学习非托管C++互操作的技术,有点小收获不敢私藏拿出来跟大家分享:作为.NET开发人员,我们有必要学习一些互操作方面的知识:尤其对一

Javascript浅谈之this_基础知识

介绍this在各种对面对象编程中起着非常重要的作用,主要用于指向调用的对象.不过在JavaScript中,this的表现存在很大差异,特别是不同执行上下文. 由前文我们知道this也是属于执行上下文中的一个属性,所有它命中注定和执行上下文脱不了干系. 复制代码 代码如下: activeExecutionContext = {VO: {...},this: thisValue}; 在Javascript中,this的取值取决于调用的模式.调用模式一共有四种:方法调用模式.函数调用模式.构造器调用模

浅谈javascript中关于日期和时间的基础知识_基础知识

前面的话 在介绍Date对象之前,首先要先了解关于日期和时间的一些知识.比如,闰年.UTC等等.深入了解这些,有助于更好地理解javascript中的Date对象.本文将介绍javascript关于日期和时间的基础知识 标准时间一般而言的标准时间是指GMT和UTC,以前是GMT,现在是UTC GMT 格林尼治标准时间(GMT)是指位于伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线 理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空

《UNIX/Linux 系统管理技术手册(第四版)》——第2章 脚本和shell 2.1 shell的基础知识

第2章 脚本和shell 好的系统管理员都要写脚本.脚本以标准和自动的方式履行系统管理员的繁杂事务,藉此把管理员的时间节省出来,以花在更重要和更有意思的任务上.从某种意义上讲,脚本也是一种低质量的文档,因为它们充当了一种权威提纲,提纲里列出完成特殊任务所需的步骤. 从复杂性来看,系统管理脚本的范围很广,小到一个脚本,简单得只封装几条静态命令,大到一个重要的软件项目,为整个站点管理主机配置和管理性数据.在本书里,我们所感兴趣的主要是系统管理员通常会碰到的较小的日常脚本项目.因此,对于较大项目才需要