IT박스

Windows 핸들이란 무엇입니까?

itboxs 2020. 6. 15. 22:00
반응형

Windows 핸들이란 무엇입니까?


Windows에서 리소스를 논의 할 때 "핸들"이란 무엇입니까? 그들은 어떻게 작동합니까?


리소스, 종종 메모리 또는 열린 파일 또는 파이프에 대한 추상 참조 값입니다.

적절하게 Windows에서 (및 일반적으로 컴퓨팅에서) 핸들은 API 사용자로부터 실제 메모리 주소를 숨겨 시스템이 실제 메모리를 프로그램에 투명하게 재구성 할 수 있도록하는 추상화입니다. 핸들을 포인터로 해석하면 메모리가 잠기고 핸들을 놓으면 포인터가 무효화됩니다. 이 경우에는 포인터 테이블에 대한 인덱스로 생각하십시오. 시스템 API 호출에 인덱스를 사용하면 시스템이 테이블의 포인터를 마음대로 변경할 수 있습니다.

대안으로, API 기록기가 API의 사용자가 주소가 가리키는 것의 세부 사항으로부터 격리되도록 의도 할 때 핸들로서 실제 포인터가 제공 될 수있다; 이 경우 핸들이 가리키는 내용이 언제든지 변경 될 수 있음을 고려해야합니다 (API 버전에서 버전으로 또는 핸들을 리턴하는 API의 호출에서 호출까지). 따라서 핸들은 단순히 불투명 한 값으로 취급되어야합니다. API 에만 의미가 있습니다.

현대의 모든 운영 체제에서 소위 "실제 포인터"라하더라도 프로세스의 가상 메모리 공간에 불투명 한 핸들이있어 O / S가 프로세스 내의 포인터를 무효화하지 않고 메모리를 관리하고 재 배열 할 수 있습니다. .


A HANDLE는 상황 별 고유 식별자입니다. 문맥에 따라, 나는 하나의 문맥에서 얻은 핸들이 HANDLEs에서 작동하는 다른 모든 문맥에서 반드시 사용될 수는 없다는 것을 의미합니다 .

예를 들어, GetModuleHandle현재로드 된 모듈에 고유 식별자를 반환합니다. 리턴 된 핸들은 모듈 핸들을 허용하는 다른 함수에서 사용될 수 있습니다. 다른 유형의 핸들이 필요한 함수에는 제공 할 수 없습니다. 예를 들어, 당신은에서 반환 된 핸들주지 수 GetModuleHandle에를 HeapDestroy하고 뭔가 분별을 할 것으로 기대합니다.

HANDLE자체는 단지 필수적인 유형입니다. 일반적으로 반드시 그런 것은 아니지만 일부 기본 유형 또는 메모리 위치에 대한 포인터입니다. 예를 들어, HANDLEby by GetModuleHandle는 실제로 모듈의 기본 가상 메모리 주소에 대한 포인터입니다. 그러나 핸들이 포인터 여야한다는 규칙은 없습니다. 핸들은 단순한 정수일 수도 있습니다 (일부 Win32 API에서 배열의 인덱스로 사용할 수 있음).

HANDLE내부 Win32 리소스에서 캡슐화 및 추상화를 제공하는 의도적으로 불투명 한 표현입니다. 이런 식으로 Win32 API는 어떤 방식 으로든 사용자 코드에 영향을 미치지 않으면 서 HANDLE 뒤의 기본 유형을 잠재적으로 변경할 수 있습니다 (적어도 아이디어입니다).

난 그냥 만들어하는 Win32 API를이 세 가지 내부 구현을 고려하고, 그 가정 Widget입니다 struct.

Widget * GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return w;
}
void * GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return reinterpret_cast<void *>(w);
}
typedef void * HANDLE;

HANDLE GetWidget (std::string name)
{
    Widget *w;

    w = findWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

첫 번째 예는 API에 대한 내부 세부 정보를 제공합니다. 사용자 코드 GetWidget가에 대한 포인터를 반환 한다는 것을 사용자에게 알려 줍니다 struct Widget. 이것은 몇 가지 결과를 초래합니다 :

  • 사용자 코드는 Widget구조체 를 정의하는 헤더 파일에 액세스 할 수 있어야합니다.
  • 사용자 코드는 반환 된 Widget구조체 의 내부 부분을 잠재적으로 수정할 수 있습니다

이러한 결과는 바람직하지 않습니다.

두 번째 예는 just을 반환하여이 내부 세부 정보를 사용자 코드에서 숨 깁니다 void *. 사용자 코드는 Widget구조체 를 정의하는 헤더에 액세스 할 필요가 없습니다 .

The third example is exactly the same as the second, but we just call the void * a HANDLE instead. Perhaps this discourages user code from trying to figure out exactly what the void * points to.

Why go through this trouble? Consider this fourth example of a newer version of this same API:

typedef void * HANDLE;

HANDLE GetWidget (std::string name)
{
    NewImprovedWidget *w;

    w = findImprovedWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

Notice that the function's interface is identical to the third example above. This means that user code can continue to use this new version of the API, without any changes, even though the "behind the scenes" implementation has changed to use the NewImprovedWidget struct instead.

The handles in these example are really just a new, presumably friendlier, name for void *, which is exactly what a HANDLE is in the Win32 API (look it up at MSDN). It provides an opaque wall between the user code and the Win32 library's internal representations that increases portability, between versions of Windows, of code that uses the Win32 API.


A HANDLE in Win32 programming is a token that represents a resource that is managed by the Windows kernel. A handle can be to a window, a file, etc.

Handles are simply a way of identifying a particulate resource that you want to work with using the Win32 APIs.

So for instance, if you want to create a Window, and show it on the screen you could do the following:

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

// Show the window.
ShowWindow(hwnd, SW_SHOW);

In the above example HWND means "a handle to a window".

If you are used to an object oriented language you can think of a HANDLE as an instance of a class with no methods who's state is only modifiable by other functions. In this case the ShowWindow function modifies the state of the Window HANDLE.

See Handles and Data Types for more information.


A handle is a unique identifier for an object managed by Windows. It's like a pointer, but not a pointer in the sence that it's not an address that could be dereferenced by user code to gain access to some data. Instead a handle is to be passed to a set of functions that can perform actions on the object the handle identifies.


A handle is like a primary key value of a record in a database.

edit 1: well, why the downvote, a primary key uniquely identifies a database record, and a handle in the Windows system uniquely identifies a window, an opened file, etc, That's what I'm saying.


So at the most basic level a HANDLE of any sort is a pointer to a pointer or

#define HANDLE void **

Now as to why you would want to use it

Lets take a setup:

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);
}

So because obj was passed by value (make a copy and give that to the function) to foo, the printf will print the original value of 1.

Now if we update foo to:

void foo(Object * bar)
{
    LargeObj lo = new LargeObj();
    bar->val++;
}

There is a chance that the printf will print the updated value of 2. But there is also the possibility that foo will cause some form of memory corruption or exception.

The reason is this while you are now using a pointer to pass obj to the function you are also allocating 2 Megs of memory, this could cause the OS to move the memory around updating the location of obj. Since you have passed the pointer by value, if obj gets moved then the OS updates the pointer but not the copy in the function and potentially causing problems.

A final update to foo of:

void foo(Object **bar){
    LargeObj lo = LargeObj();
    Object * b = &bar;
    b->val++;
}

This will always print the updated value.

See, when the compiler allocates memory for pointers it marks them as immovable, so any re-shuffling of memory caused by the large object being allocated the value passed to the function will point to the correct address to find out the final location in memory to update.

Any particular types of HANDLEs (hWnd, FILE, etc) are domain specific and point to a certain type of structure to protect against memory corruption.


Think of the window in Windows as being a struct that describes it. This struct is an internal part of Windows and you don't need to know the details of it. Instead, Windows provides a typedef for pointer to struct for that struct. That's the "handle" by which you can get hold on the window.,

참고URL : https://stackoverflow.com/questions/902967/what-is-a-windows-handle

반응형