关于句柄和指针之间的转换 大家好,问大家一个很简单的问题,已知一个句柄值,想得到他的指针,那么有几种办法,各有什么优缺点没? 本人在图像处理常碰到是用GlobalLock函数的,但是有时使用时会遇到问题,所以问大家一下这个问题。希望有达人帮忙解决一下。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我问一个具体的例子好了:我在做视频捕获时,采用Windows提供的API,把一帧图像采集到剪切板后,用GETclipboardData函数取得位图的句柄,但是我要读取所有的图像数据,那么只能用指针喽,如果用句柄该如何处理,我以前的理解句柄只是一个16位或32位的常数值而已,没把它当作指针来理解的。 句柄不可以当成指针,指针可以直接指向一个内存地址.使用指针就可以对这块内存进行操作.但在windows中有些对象如内核对象,GDI对象如果用户直接操作内存可能会引起整个操作系统崩溃,所以Windows提供句柄来标识这些对象的位置,并提供了一系列操作句柄的函数来处理这些对象. 句柄可以认为是你的身份证在系统范围内是唯一的,指针可以认为是对你所在位置的描述,比如北京,上海通过指针可以直接找到你,通过句柄可以唯一标识你。FromHandle,GetSafeHwnd,GetSafeHandle,m_hWnd,等可以实现互换。 同意 littlebao(爱拼才会赢)! window这么庞大,没有个东西进行区分,操作系统如何识别呢?--句柄 同意 littlebao(爱拼才会赢) 的观点!不过,我还要加上一个函数:GetSafeHdc;FromHandle,GetSafeHwnd,GetSafeHandle,m_hWnd,GetSafeHdc等这些函数可以实现互换! 句柄……不能说是指针吧?这个东西Windows各个不同的部分想怎么解释就怎么解释的,一定要说成指针比较困难…… fanqing(火影忍者+28%(准备学习进程/线程)) :当然不能只看typedef,傻子都知道HANDLE在某些运行库的头文件中被定义成void*.可是在实际处理中void*是什么呢?最终还不是一个整数值?首先你要搞明白HANDLE不是C/C++中的概念,而是操作系统的概念,所以不要只看typedef。另外FromHandle也并不能把句柄转换成指针。而只是用一个类把Handle包装一下,并得到这个类的对象指针 http://dev.csdn.net/article/54/54250.shtm http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/usingtheclipboard.asp从Creating a Clipboard Viewer Window开始看 看来看去我觉得还是一个三角的楼主比这堆星星们水平高。至少楼主还懂得要想访问一个句柄标识的内存必须先GlobalLock才能得到一个指向内存的指针。我觉得楼主出错的原因可能是1)对Clipboard中数据格式判断不对,是否用GetPriorityClipboardFormat判断过?2)有没有什么语句把OpenClipboard给跳过去了?3)是否用IsClipboardDataAvailable判断过当前数据合法?如果都判断过再进行下一步。如果是CF_BITMAP型的可以用GetClipboardData得到一个全局内存的句柄。这个全局句柄就是一个HBITMAP,可以Attach到一个CBitmap,也可以直接用BitBlt画出来,或者用BITMAP bm; GetObject(hBmp, sizeof(bm), &bm)为构造一个BITMAP结构。如果是CF_DIB型的,必须对内存进行操作: BITMAPINFOHEADER* pBih = (BITMAPINFOHEADER*)::GlobalLock(hBmp); int width, height, right; BITMAP bm; if (pBih->biSize == sizeof(BITMAPCOREHEADER)) { bm.bmWidth = pBih->bcWidth; bm.bmHeight= pBih->bcHeight; bm.bmBitsPixel= pBih->bcBitCount; bm.bmType = BI_RGB; bm.bmBits = PBYTE(pBih) + pBih->biSize + (bm.bmBitsPixel>8?0:1<<bm.bmBitsPixel)*3; } else { bm.bmWidth = pBih->biWidth; bm.bmHeight= pBih->biHeight; bm.bmBitsPixel= pBih->biBitCount; bm.bmType = pBih->biCompression; long color = pBih->biClrUsed? pBih->biClrUsed : (bm.bmBitsPixel>8?0:1<<bm.bmBitsPixel)); bm.bmBits = PBYTE(pBih) + pBih->biSize + color*4; }另外,fanqing(火影忍者+28%(准备学习进程/线程)) ( ) 如果你去看不同的类库,甚至同一类库不同版本你就会发现,并不是所有类库都把HANDLE定义成指针(事实上只有非常少的类库把HANDLE定义成了指针)。如果还不明白可以举一个例子,你可以声明一个short变量但里面放字符串,也可以声明一个char buf[]然后用一个流向里面注入二进制数据。HANDLE的值有时会等于GlobalLock()后的指针的值,记不清楚是在什么时候,好象是在分配一个不可Discarded的全局内存时这两个值是相同的,但我个人认为这并不能证明他们有什么关系。并且我也不觉得句柄是对指针进行了封装。句柄就是个整数值。操作系统维护一个表,使User能根据句柄找到不断变化地址的那块内存。当然如果你就认为是个指针那也没办法,因为0xFFFF还可以标识一个地址呢。 非常感谢各位,特别是opentuxedo(开缝的燕尾服) ,谢谢你的详细指点。 结束了.白忙了.#ifdef STRICTtypedef void *HANDLE;//指针#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name#elsetypedef PVOID HANDLE;#define DECLARE_HANDLE(name) typedef HANDLE name#endif自己看看net代码别告诉我是什么操作系统的概念,不是c++的概念.实践才是真理(别老相信书上--他掩盖了太多本质) 补充:<看来看去我觉得还是一个三角的楼主比这堆星星们水平高。至少楼主还懂得要想访问一个句柄标识的内存必须先GlobalLock才能得到一个指向内存的指针。>这句话本生就是错误的<内存必须先GlobalLock才能得到一个指向内存的指针>--建议你仔细看看书.星星多并不代表什么,只代码这个人好助人.讨厌以星星的多少来讥讽别人. 菜单 mfc debug版本编译正确,但release编译与debug不同是为什么呢 关于API初学的问题 如何实现双击一文本文件,不是打开而是删除它? 高分问个问题:当窗口最小化或者隐藏时,如何获取窗口指定点的象素信息? 请教:关于CDialog 和CView类的关系. this+1什么意思? 我下载的.chm帮助文件的字太小,怎么变大? 白送分的问题 已知坐标点,如何画一个这样的图? 高手请进,关于在自己的程序中使用搜索引擎的问题! 有点难度的问题
我在做视频捕获时,采用Windows提供的API,把一帧图像采集到剪切板后,用GETclipboardData函数取得位图的句柄,但是我要读取所有的图像数据,那么只能用指针喽,如果用句柄该如何处理,我以前的理解句柄只是一个16位或32位的常数值而已,没把它当作指针来理解的。
指针可以认为是对你所在位置的描述,比如北京,上海
通过指针可以直接找到你,通过句柄可以唯一标识你。
FromHandle,GetSafeHwnd,GetSafeHandle,m_hWnd,等可以实现互换。
FromHandle,GetSafeHwnd,GetSafeHandle,m_hWnd,GetSafeHdc等这些函数可以实现互换!
当然不能只看typedef,傻子都知道HANDLE在某些运行库的头文件中被定义成void*.可是在实际处理中void*是什么呢?最终还不是一个整数值?首先你要搞明白HANDLE不是C/C++中的概念,而是操作系统的概念,所以不要只看typedef。
另外FromHandle也并不能把句柄转换成指针。而只是用一个类把Handle包装一下,并得到这个类的对象指针
从Creating a Clipboard Viewer Window开始看
我觉得楼主出错的原因可能是
1)对Clipboard中数据格式判断不对,是否用GetPriorityClipboardFormat判断过?
2)有没有什么语句把OpenClipboard给跳过去了?
3)是否用IsClipboardDataAvailable判断过当前数据合法?
如果都判断过再进行下一步。
如果是CF_BITMAP型的可以用GetClipboardData得到一个全局内存的句柄。这个全局句柄就是一个HBITMAP,可以Attach到一个CBitmap,也可以直接用BitBlt画出来,或者用BITMAP bm; GetObject(hBmp, sizeof(bm), &bm)为构造一个BITMAP结构。
如果是CF_DIB型的,必须对内存进行操作:
BITMAPINFOHEADER* pBih = (BITMAPINFOHEADER*)::GlobalLock(hBmp);
int width, height, right;
BITMAP bm;
if (pBih->biSize == sizeof(BITMAPCOREHEADER))
{
bm.bmWidth = pBih->bcWidth;
bm.bmHeight= pBih->bcHeight;
bm.bmBitsPixel= pBih->bcBitCount;
bm.bmType = BI_RGB;
bm.bmBits = PBYTE(pBih) + pBih->biSize +
(bm.bmBitsPixel>8?0:1<<bm.bmBitsPixel)*3;
}
else {
bm.bmWidth = pBih->biWidth;
bm.bmHeight= pBih->biHeight;
bm.bmBitsPixel= pBih->biBitCount;
bm.bmType = pBih->biCompression;
long color = pBih->biClrUsed?
pBih->biClrUsed : (bm.bmBitsPixel>8?0:1<<bm.bmBitsPixel));
bm.bmBits = PBYTE(pBih) + pBih->biSize + color*4;
}另外,fanqing(火影忍者+28%(准备学习进程/线程)) ( ) 如果你去看不同的类库,甚至同一类库不同版本你就会发现,并不是所有类库都把HANDLE定义成指针(事实上只有非常少的类库把HANDLE定义成了指针)。如果还不明白可以举一个例子,你可以声明一个short变量但里面放字符串,也可以声明一个char buf[]然后用一个流向里面注入二进制数据。HANDLE的值有时会等于GlobalLock()后的指针的值,记不清楚是在什么时候,好象是在分配一个不可Discarded的全局内存时这两个值是相同的,但我个人认为这并不能证明他们有什么关系。并且我也不觉得句柄是对指针进行了封装。句柄就是个整数值。操作系统维护一个表,使User能根据句柄找到不断变化地址的那块内存。当然如果你就认为是个指针那也没办法,因为0xFFFF还可以标识一个地址呢。
typedef void *HANDLE;//指针
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif自己看看net代码
别告诉我是什么操作系统的概念,不是c++的概念.实践才是真理(别老相信书上--他掩盖了太多本质)
这句话本生就是错误的<内存必须先GlobalLock才能得到一个指向内存的指针>--建议你仔细看看书.
星星多并不代表什么,只代码这个人好助人.讨厌以星星的多少来讥讽别人.