Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是Windows句柄?_Windows_Handle - Fatal编程技术网

什么是Windows句柄?

什么是Windows句柄?,windows,handle,Windows,Handle,在Windows中讨论资源时,“句柄”是什么?它们是如何工作的?它是对资源的抽象引用值,通常是内存、打开的文件或管道 正确地说,在Windows中(通常在计算中),句柄是对API用户隐藏真实内存地址的抽象,允许系统对程序透明地重新组织物理内存。将句柄解析为指针会锁定内存,释放句柄会使指针无效。在这种情况下,可以将其视为指针表的索引。。。您将索引用于系统API调用,系统可以随意更改表中的指针 或者,当API编写器打算将API的用户与地址返回指向的具体内容隔离时,可以给出一个实指针作为句柄;在这种情

在Windows中讨论资源时,“句柄”是什么?它们是如何工作的?

它是对资源的抽象引用值,通常是内存、打开的文件或管道

正确地说,在Windows中(通常在计算中),句柄是对API用户隐藏真实内存地址的抽象,允许系统对程序透明地重新组织物理内存。将句柄解析为指针会锁定内存,释放句柄会使指针无效。在这种情况下,可以将其视为指针表的索引。。。您将索引用于系统API调用,系统可以随意更改表中的指针

或者,当API编写器打算将API的用户与地址返回指向的具体内容隔离时,可以给出一个实指针作为句柄;在这种情况下,必须考虑句柄指向的内容可能随时发生变化(从一个API版本到另一个版本,甚至从返回句柄的API的一个调用到另一个调用)——因此,句柄应被视为仅对API有意义的不透明值


我应该补充一点,在任何现代操作系统中,即使是所谓的“真实指针”也仍然是进程虚拟内存空间中的不透明句柄,这使得O/S能够管理和重新排列内存,而不会使进程中的指针失效。

将Windows中的窗口看作是一个描述它的结构。此结构是Windows的内部部分,您不需要知道它的详细信息。相反,Windows为指向该结构的结构的指针提供了typedef。这是您可以用来控制窗口的“句柄”。

Win32编程中的句柄是表示由Windows内核管理的资源的令牌。句柄可以是窗口、文件等的句柄

句柄只是标识要使用Win32 API处理的微粒资源的一种方式

例如,如果您想创建一个窗口,并在屏幕上显示它,您可以执行以下操作:

// Create the window
HWND hwnd = CreateWindow(...); 
if (!hwnd)
   return; // hwnd not created

// Show the window.
ShowWindow(hwnd, SW_SHOW);
在上面的示例中,HWND表示“窗口句柄”

如果您习惯了面向对象的语言,您可以将句柄视为没有方法的类的实例,该类的状态只能由其他函数修改。在这种情况下,ShowWindow函数修改窗口句柄的状态


有关更多信息,请参阅

句柄是上下文特定的唯一标识符。通过上下文特定,我的意思是,从一个上下文中获得的句柄不一定可以用于任何其他同样适用于
handle
s的aribtrary上下文

例如,
GetModuleHandle
为当前加载的模块返回唯一标识符。返回的句柄可以在接受模块句柄的其他函数中使用。不能将其指定给需要其他类型句柄的函数。例如,您不能将从
GetModuleHandle
返回的句柄赋给
HeapDestroy
并期望它做一些合理的事情

句柄本身就是一个整数类型。通常(但不一定)它是指向某个底层类型或内存位置的指针。例如,由
GetModuleHandle
返回的
句柄实际上是指向模块的基本虚拟内存地址的指针。但没有规定句柄必须是指针。句柄也可以是一个简单的整数(可能被某些Win32 API用作数组的索引)

HANDLE
s是故意不透明的表示形式,提供对内部Win32资源的封装和抽象。通过这种方式,Win32 API可以潜在地更改句柄背后的底层类型,而不会以任何方式影响用户代码(至少这是个想法)

考虑我刚刚编写的Win32 API的这三种不同的内部实现,并假设
小部件
是一个
结构

Widget*GetWidget(std::string name)
{
Widget*w;
w=findWidget(名称);
返回w;
}
void*GetWidget(std::string name)
{
Widget*w;
w=findWidget(名称);
返回重新解释(w);
}
typedef void*句柄;
句柄GetWidget(std::字符串名称)
{
Widget*w;
w=findWidget(名称);
返回重新解释(w);
}
第一个示例公开了API的内部细节:它允许用户代码知道
GetWidget
返回指向
struct Widget
的指针。这有两个后果:

  • 用户代码必须能够访问定义
    小部件的头文件
    结构
  • 用户代码可能会修改返回的
    Widget
    struct的内部部分
这两种后果都可能是不可取的

第二个示例通过仅返回
void*
来对用户代码隐藏此内部细节。用户代码不需要访问定义
Widget
struct的头

第三个示例与第二个示例完全相同,但我们只调用
void*
a
HANDLE
。这可能会阻碍用户代码准确地找出
void*
所指的内容

为什么要经历这些麻烦?考虑这个相同API的更新版本的第四个例子:

typedef void*句柄;
句柄GetWidget(std::字符串名称)
{
新改进的widget*w;
w=findImprovedWidget(名称);
返回重新解释(w);
}
请注意,函数的接口与上面的第三个示例相同。这意味着,即使“幕后”实现已改为使用
NewImprovedWidget
struct,用户代码仍可以继续使用此新版本的API,而无需任何更改

这些示例中的句柄实际上是ju
#define HANDLE void **
class Object{
   int Value;
}

class LargeObj{

   char * val;
   LargeObj()
   {
      val = malloc(2048 * 1000);
   }

}

void foo(Object bar){
    LargeObj lo = new LargeObj();
    bar.Value++;
}

void main()
{
   Object obj = new Object();
   obj.val = 1;
   foo(obj);
   printf("%d", obj.val);
}
void foo(Object * bar)
{
    LargeObj lo = new LargeObj();
    bar->val++;
}
void foo(Object **bar){
    LargeObj lo = LargeObj();
    Object * b = &bar;
    b->val++;
}