一句话:为了满足进程间通信,使用了clipboard的方法,clipboard是系统提供的一段任何进程都可以访问的公共内存块,malloc 和new分配的动态内存块是在进程的私有地址空间分配的,所以必须用GlobalAlloc函数才能在系统的公共内存空间申请到内存块。

关于内存分配问题,可参见msdn的:

Comparing Memory Allocation Methods:https://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

下面的总结部分来自http://www.cnblogs.com/BoyXiao/archive/2010/12/25/1916677.html 因为他总结的很好,我都懒的改了,直接拷贝一部分。

ClipBoard的作用:

在启动一个进程时,操作系统会为该进程分配4GB的私有地址空间,该地址空间只有该进程自己可以访问,其余的进程无法访问该地址空间。 从而任意两进程间不能相互访问对方的私有地址空间,从而无法完成进程间通信。 为了完成两进程间的通信,操作系统另外划分出一块内存,这一块内存不为任何的进程所私有,但是任何的进程又都可以访问这块内存, 那么 进程 A 就可以往这块内存中存放数据 Data ,然后 进程 B 也是可以访问这块内存的,从而 进程 B 就可以访问到数据 Data 了, 这样不就实现了 进程 A 和 进程 B 之间的通信了 !!! 而上面的这种思路就是ClipBoard了,关于pipe和mail slot也是进程间通信方式,以后再谈。

定义:

剪贴板是由操作系统维护的一块内存区域,这块内存区域不属于任何单独的进程,但是每一个进程又都可以访问这块内存区域, 而实质上当在一个进程中复制数据时,就是将数据放到该内存区域中,而当在另一个进程中粘贴数据时,则是从该块内存区域中取出数据。

问题:剪贴板中的内存从何而来?

对于操作系统而言,什么时候分配clipBoard内存比较合适呢,由于不知道要复制的内容大小,因此不可能在操作系统启动的时候为其分配内存, 要想动态分配该内存,那有一种方案,就是当我的程序要往剪贴板中放置数据的时候来确定要分配给剪贴板的内存的大小, 很明显,既然我都知道要往剪贴板中放置那些数据了,自然我也就知道了这些数据的长度, 那么我就可以以这个数据长度来给剪贴板分配内存了,这是很动态的了吧,所以这种方案是可取的, 但关键是,当我们以前在程序中分配内存的时候,都是使用的标准 C 运行库中的 malloc 或者是 C++ 中的 new 关键字, (当然分配内存还有很多其他的函数,比如就有内核中的执行体中就有很多分配内存的函数,这里不讨论), 而使用 malloc 或者 new 有一个问题,那就是,用这个两个东西来分配的内存空间都是在当前进程的私有地址空间上分配内存, 也就是它们两个东东所分配的内存空间为进程私有地址空间所有,并不为所有进程所共享,上面提到了,任何进程之间都是不能访问对方的私有地址空间的,你把剪贴板中的内存分配到了你当前进程的私有地址空间上, 而其他进程又不能访问你这个进程的私有地址空间,那怎么能够访问剪贴板呢? 很明显,不能使用 malloc 和 new 关键字来分配内存给剪贴板。 我们应该要使用另外一个特殊一点的函数来分配内存给剪贴板, 这个特殊函数所分配的内存不能够是在进程的私有地址空间上分配,而是要在全局地址空间上分配内存, 这样这个函数所分配的内存才能够被所有的进程所共享,这样,剪贴板中的数据就可以被其他的进程所访问了。

GlobalAlloc 函数

GlobalAlloc 函数是从堆上分配指定数目的字节, 与其他的内存管理函数相比,全局内存函数的运行速度会稍微慢一些, 但是全局函数支持动态数据交换,同时,其分配的内存也不为任何一个进程所私有,而是由操作系统来管理这块内存, 所以用在给剪贴板分配内存空间是很适合的。 这里有读者可能会问: 为什么我们在自己的应用程序中不使用 GlobalAlloc 函数来分配内存,而是要使用 malloc 或者 new 来实现? 其实,这个也只用稍微想想就知道了,你想啊,使用 malloc 或者 new 分配的内存是在进程的私有地址空间上分配的, 这片私有地址空间都是归这个进程所拥有,所管理的,自然,在以后对这块内存的读写会快很多的, 而全局内存不属于这个进程,你下次要去访问全局内存的时候,还得通过映射转换,这样肯定是运行效率低下一些了, 简单点就可以这样理解,你使用 malloc 或者 new 分配的内存和你的进程隔得很近,程序要过去拿数据 - 得,很近吧, 而是用 GlobalAlloc 函数分配的内存和你的进程隔得很远,程序要过去拿数据 - 太远了,耗时。 应用程序在调用了 SetClipboardData 函数之后, 系统就拥有了 hMem 参数所标识的数据对象,该应用程序可以读取这个数据对象, 但是在应用程序调用 CloseClipboard 函数之前,它都是不能释放该对象的句柄的,或者锁定这个句柄, 如果 hMem 标识一个内存对象,那么这个对象必须是利用 GMEM_MOVEABLE 标识调用 GlobalAlloc 函数为其分配内存的。

关于Clipboard和GlobalAlloc函数的关系的更多相关文章

  1. mongo的runCommand与集合操作函数的关系

    除了特殊注释外,本文的测试结果均基于 spring-data-mongodb:1.10.6.RELEASE(spring-boot-starter:1.5.6.RELEASE),MongoDB 3.0 ...

  2. legend---十二、js中的js语句和函数和ready函数的关系是什么

    legend---十二.js中的js语句和函数和ready函数的关系是什么 一.总结 一句话总结: 函数和全局变量不必放到ready函数中 语句(调用函数和全局变量)的必须放到ready函数中 1.在 ...

  3. 标准c库函数和linux系统函数的关系

    c库IO函数的工作流程 c库函数与系统函数的关系 虚拟地址空间 文件描述符

  4. 函数式编程—函数的关系—is-a、has-a、use-a

    is-a:函数的实现与函数类型的关系: has-a:匿名(闭包)函数的创建者与匿名函数的关系:匿名函数与环境和上下文(函数)的关系: use-a:高阶函数与参量函数的关系: 函数式编程的基本功之一就是 ...

  5. 【编程开发】 C与C++中的关于函数指针的强制类型转换与指针函数的关系

    [编程开发] C与C++中的关于函数指针的强制类型转换与指针函数的关系 标签: [编程开发] [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 以 ...

  6. 函数与关系实例,函数运算与SQL,试验与关系元组

    函数是一个集合,它的每个元素都是二元组或多元组.例如 f = { (x, y) | x∈R & y∈R & y = 2x } ,g = { (x, y, z) | (x, y, z)∈ ...

  7. PHP-CGI 进程 CPU 100% 与 file_get_contents 函数的关系

    [文章作者:张宴 本文版本:v1.0 最后修改:2011.08.05 转载请注明原文链接:http://blog.s135.com/file_get_contents/] 有时候,运行 Nginx.P ...

  8. js中对象与函数的关系

    首先什么是对象?根据W3C上面的解释JS中所有事物都是对象,对象是拥有属性和方法的数据,由此可以看出基本值类型不是对象(number.string.Boolean.Undefined),剩下的引用类型 ...

  9. 一.oracle的SQL中group by使用的情况(与聚合函数的关系)

    SELECT r.industry_1,r.industry_2,r.agent_id,r.agent_name,COUNT(DISTINCT r.customer_name_a)数据总量,COUNT ...

随机推荐

  1. Webhook

    Webhook就是用户通过自定义回调函数的方式来改变Web应用的一种行为,这些回调函数可以由不是该Web应用官方的第三方用户或者开发人员来维护,修改.通过Webhook,你可以自定义一些行为通知到指定 ...

  2. 【ios开发学习 - 第二课】iOS项目文件夹结构

    文件夹结构 AppDelegate Models Macro General Helpers Vendors Sections Resources   一个合理的文件夹结构首先应该是清晰的.让人一眼看 ...

  3. [Python] Manage Dependencies with Python Virtual Environments

    Virtual Environments ensure that dependencies from one Python application don’t overwrite the depend ...

  4. 【HDOJ 5384】Danganronpa

    [HDOJ 5384]Danganronpa AC自己主动机. .. 当时感觉用字典树 标神也往自己主动机想来着..手太生加上时间紧迫也没敲--回来一看题解什么AB同一时候建自己主动机...顿时愣了 ...

  5. 120.VS调试技巧

    设置断点调试 在一行代码的左侧点击即可设置断点,按F5(调试->开始调试)即可运行到第一个端点处暂停 逐语句调试 按F11(调试->逐语句)即可开始一步一步执行 逐过程调试 按F10(调试 ...

  6. 【习题 8-8 UVA - 1612】Guess

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] double千万不要用==判断相等... 而且两个保留2位有效数字的数字x,y 判断它们相等应该这样. int temp1 = ro ...

  7. Java中join和yield的作用

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 1.   A.join,在API中的解释是,堵塞当前线程B,直到A执行完毕并死掉,再执行B. 用一个 ...

  8. mvc定时执行任务(获取气象台的气象数据,定时新增)

    1.定时任务: gloabl.asax文件Application_Start()方法注册: System.Timers.Timer t = new System.Timers.Timer(theInt ...

  9. HTTP (httpwebrequest)

    1.GET请求: public static string Get(string url) { string buffer = ""; try { HttpWebRequest r ...

  10. hive学习笔记-高级查询

    聚合函数 count计数 count(*):不全都是NULL.就加1:count(1):当仅仅要有一列是NULL就不会加1:count(col):当col列不为空就会加1 sum求和 sum(可转成数 ...