一句话:为了满足进程间通信,使用了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. struts2 结合extjs实现的一个登录实例

    一.先搭建好struts2,能够通过myeclipse高速搭建. 二.再导入extjs所需的库文件. 三.写一个实体类User package com.ext.model; public class ...

  2. 第一天,Mysql安装,DDL(数据库定义语言),DBA,DML(数据库操纵语言),导入外面的sql文件

    把“D:\mysql-5.6.22-winx64\bin”添加到系统环境变量path中了,然后在任意目录可访问mysql等命令,这样如登录等操作就不需要进入MySQL安装目录才好执行! MySQL下载 ...

  3. HDU 4405 概率期望DP

    有 0到 n 个格子.掷骰子走路,求出到终点的数学期望,有飞行的路线. dp[i] 存储在i位置走到终点的期望. 转移方程dp[i]=(dp[i+1] ----> dp[i+6])/6+1; 有 ...

  4. 解决wget下载文件名乱码的一些方法

    在下载用apache或者nginx做的索引目录时,遇到文件名乱码问题.搜索了不少资料,尝试了好几种方案,大家可以结合使用. 一般情况下加上–restrict-file-names=nocontrol参 ...

  5. 跨域使用onmessage实现方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. rpm---rpm包管理

    rpm命令是RPM软件包的管理工具.rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎.逐渐受到其他发行版的采用.RPM ...

  7. POJ 4047 Garden

    Garden Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 404 ...

  8. AtomicInteger类

    今天写代码.尝试使用了AtomicInteger这个类,感觉使用起来非常爽,特别适用于高并发訪问.能保证i++,++id等系列操作的原子性. ++i和i++操作并非线程安全的.非常多人会用到synch ...

  9. Exploring Micro-frameworks: Spring Boot--转载

    原文地址:http://www.infoq.com/articles/microframeworks1-spring-boot Spring Boot is a brand new framework ...

  10. 如何优雅的写UI——(1)MFC六大核心机制-程序初始化

    很多做软件开发的人都有一种对事情刨根问底的精神,例如我们一直在用的MFC,很方便,不用学太多原理性的知识就可以做出各种窗口程序,但喜欢钻研的朋友肯定想知道,到底微软帮我们做了些什么,让我们在它的框架下 ...