문제

무엇을"처리"설명할 때 자원 Windows?그들은 어떻게 일하는가?

도움이 되었습니까?

해결책

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

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

또는 API 작가가 API의 사용자가 주소가 반환 한 내용의 세부 사항에서 절연 될 때 실제 포인터가 핸들로 제공 될 수있다. 이 경우 핸들이 언제라도 가리키는 내용 (API 버전에서 버전에서 또는 핸들을 반환하는 API의 호출로)로 변경 될 수있는 것으로 간주해야합니다. 따라서 핸들은 단순히 불투명 값으로 취급되어야합니다. 의미가 있습니다 API에.

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

다른 팁

HANDLE 컨텍스트 별 고유 식별자입니다. 문맥별로, 한 컨텍스트에서 얻은 핸들이 다른 aribtary 컨텍스트에서도 반드시 사용될 수는 없다는 것을 의미합니다. HANDLE에스.

예를 들어, GetModuleHandle 고유 식별자를 현재로드 된 모듈로 반환합니다. 반환 된 핸들은 모듈 핸들을 허용하는 다른 기능에서 사용할 수 있습니다. 다른 유형의 핸들이 필요한 기능에는 주어질 수 없습니다. 예를 들어, 반환 된 손잡이를 줄 수 없었습니다. GetModuleHandle 에게 HeapDestroy 그리고 현명한 일을 할 것으로 기대합니다.

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

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

내가 방금 구성한 Win32 API의 세 가지 내부 구현을 고려하고 Widget a 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 구조

이 두 가지 결과는 바람직하지 않을 수 있습니다.

두 번째 예제는이 내부 세부 사항을 사용자 코드에서 숨 깁니다. void *. 사용자 코드는 Widget 구조.

세 번째 예는 두 번째 예와 정확히 동일하지만 우리는 void *HANDLE 대신에. 아마도 이것은 사용자 코드가 정확히 무엇을 void * 를 가리키다.

이 문제를 겪는 이유는 무엇입니까? 이 동일한 API의 최신 버전의 네 번째 예를 고려하십시오.

typedef void * HANDLE;

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

    w = findImprovedWidget(name);

    return reinterpret_cast<HANDLE>(w);
}

함수의 인터페이스는 위의 세 번째 예와 동일합니다. 즉, "비하인드"구현이 사용되도록 변경 되었음에도 불구하고 사용자 코드는 변경 없이이 새 버전의 API를 계속 사용할 수 있습니다. NewImprovedWidget 대신 구조.

이 예의 핸들은 실제로 새로운 것, 아마도 더 친근한 이름 일뿐입니다. void *, 이것이 바로 무엇입니다 HANDLE Win32 API에 있습니다 (찾아보십시오 MSDN에서). 사용자 코드와 Win32 API를 사용하는 코드의 휴대 성을 향상시키는 사용자 코드와 Win32 라이브러리의 내부 표현간에 불투명 한 벽을 제공합니다.

Win32 프로그래밍의 핸들은 Windows 커널에서 관리하는 리소스를 나타내는 토큰입니다. 핸들은 창, 파일 등에있을 수 있습니다.

핸들은 단순히 Win32 API를 사용하여 작업하려는 미립자 리소스를 식별하는 방법입니다.

예를 들어, 창을 만들고 화면에 표시하려면 다음을 수행 할 수 있습니다.

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

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

위의 예에서 HWND는 "창에 대한 핸들"을 의미합니다.

객체 지향 언어에 익숙한 경우, 다른 기능에 의해서만 수정 가능한 방법이없는 방법이없는 클래스의 인스턴스로 핸들을 생각할 수 있습니다. 이 경우 쇼 와디 함수는 창 핸들의 상태를 수정합니다.

보다 처리 및 데이터 유형 자세한 내용은.

핸들은 Windows에서 관리하는 객체의 고유 식별자입니다. 이것의 포인터처럼, 하지만 포인터가 아닙니다 또한 일부 데이터에 대한 액세스를 얻기 위해 사용자 코드에 의해 부정 할 수있는 주소가 아닙니다. 대신 핸들은 핸들이 식별하는 객체에서 동작을 수행 할 수있는 일련의 함수로 전달됩니다.

핸들은 데이터베이스에서 레코드의 주요 키 값과 같습니다.

편집 1 : 글쎄, 기본 키인 Downvote가 데이터베이스 레코드를 고유하게 식별하고 Windows 시스템의 핸들이 창, 열린 파일 등을 고유하게 식별하는 이유는 내가 말하는 것입니다.

도록 가장 기본적인 수준에서 핸들의 모든 종류를 가리키는 포인터 또는 포인터

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

그렇기 때문에 obj 전달되었으로 가치(복사본을 만들고 그것을 주는 기능)을 foo,printf 것 인쇄를 원래의 값은 1 입니다.

지금 우리가 업데이트 foo to:

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

기회가 있는 printf 인쇄할 것입 업데이트 값을 2.하지만 가능성이있는 foo 원인이됩니다 어떤 형태의 메모리 손상 또는 예외는 아니다.

그 이유는 이는 동안 당신은 지금에 대한 포인터를 사용하여 전달 obj 한 기능도 할당 2 메가의 메모리,이 발생할 수 있습 OS 이동하는 메모리 주변의 위치 업데이트 obj.했기 때문에 전달되는 포인터 값에 의한 경우,obj 얻으로 이동한 다음 OS 업데이트를 포인터를 하지 않은 복사 기능과 잠재적으로 일으키는 문제입니다.

최종 업데이트를 foo 의:

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

이상 인쇄 업데이트 값입니다.

볼 때,컴파일러를 할당하는 메모리 포인터에 표시로 움직일 수 없다,그래서 어떤 다시 섞의 메모리에 의해 발생 큰 객체를 할당되는 값을 전달하는 기능을 가리킨 정확한 주소를 찾을 최종 위치에서 메모리를 업데이트합니다.

어떤 특정 종류의 손잡이(hWnd,파일,etc.)은 도메인의 특정 지점을 특정 유형의 구조에 대한 보호 메모리 손상입니다.

창의 창을 창의 창을 설명하는 구조물이라고 생각하십시오. 이 구조물은 창의 내부 부분이며 세부 사항을 알 필요가 없습니다. 대신, Windows는 해당 구조물을 위해 포인터를위한 타입을 제공합니다. 그것은 당신이 창문을 잡을 수있는 "핸들"입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top