Что такое дескриптор Windows?

Вероятно, это зависит от деталей движка рендеринга на каждой платформе, которые могут быть трудно модифицировать. Мои предложения (непроверенные из-за нехватки времени и доступа к Windows):

  • установите пакет cairoDevice и используйте Cairo_png(). Согласно документации:
 This functions the same as any other R graphics device. You may
 use the conventional plot commands and expect essentially the same
 output, except that everything is anti-aliased (similar to other
 vector-based devices like Quartz). Alpha-blending is supported, as
 is enhanced interactivity via ‘getGraphicsEvent’. The device
 should work the same across all supported platforms (Mac, Windows,
 and Linux).
  • Измените PNG с гораздо более высоким разрешением (или выведите данные из R в формате PDF) и используйте ImageMagick ( convert) или какой-либо другой инструмент для получения сглаженной версии.
141
задан akashchandrakar 3 December 2014 в 17:02
поделиться

6 ответов

Это абстрактное значение ссылки на ресурс, часто память, открытый файл или канал.

Правильно в Windows (и обычно в вычислениях) дескриптор - это абстракция, которая скрывает реальный адрес памяти от пользователя API, позволяя системе прозрачно реорганизовать физическую память для программы. Преобразование дескриптора в указатель блокирует память, а освобождение дескриптора делает указатель недействительным. В этом случае подумайте об этом как об индексе в таблице указателей ... вы используете индекс для системных вызовов API, и система может изменять указатель в таблице по своему желанию.

В качестве альтернативы может быть указан реальный указатель в качестве дескриптора, когда автор API намеревается изолировать пользователя API от специфики того, на что указывает возвращаемый адрес;

156
ответ дан 23 November 2019 в 22:35
поделиться

A HANDLE - это контекстно-зависимый уникальный идентификатор. Под контекстно-зависимым я подразумеваю, что дескриптор, полученный из одного контекста, не может обязательно использоваться в любом другом произвольном контексте, который также работает с HANDLE s.

Например, GetModuleHandle возвращает уникальный идентификатор загруженного в данный момент модуля. Возвращенный дескриптор может использоваться в других функциях, которые принимают дескрипторы модуля. Его нельзя назначать функциям, требующим других типов дескрипторов. Например, вы не могли передать дескриптор, возвращенный из GetModuleHandle , в HeapDestroy и ожидать, что он сделает что-то разумное.

Сам HANDLE - это просто интегральный тип. Обычно, но не обязательно, это указатель на некоторый базовый тип или место в памяти. Например, HANDLE , возвращаемый GetModuleHandle , на самом деле является указателем на базовый адрес виртуальной памяти модуля. Но нет правила, согласно которому дескрипторы должны быть указателями. Дескриптор также может быть простым целым числом (которое может быть использовано некоторым Win32 API в качестве индекса в массиве).

HANDLE - это намеренно непрозрачные представления, которые обеспечивают инкапсуляцию и абстракцию от внутренних ресурсов Win32. Таким образом, API Win32 потенциально могут изменить базовый тип HANDLE, не влияя каким-либо образом на код пользователя (по крайней мере, это идея).

Рассмотрим эти три различных внутренних реализации Win32 API, которые я только что придумал. , и предположим, что Виджет - это 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 struct
  • , код пользователя потенциально может изменять внутренние части возвращенного Widget struct

Оба эти последствия могут быть нежелательными.

Второй пример скрывает эту внутреннюю деталь от пользовательского кода, возвращая только 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.

91
ответ дан 23 November 2019 в 22:35
поделиться

HANDLE в программировании Win32 - это маркер, представляющий ресурс, которым управляет ядро ​​Windows. Дескриптор может относиться к окну, файлу и т. Д.

Дескрипторы - это просто способ идентификации ресурса твердых частиц, с которым вы хотите работать, используя API Win32.

Так, например, если вы хотите создать Window и отобразить его на экране, вы можете сделать следующее:

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

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

В приведенном выше примере HWND означает «дескриптор окна».

Если вы привыкли к объектно-ориентированному языку, вы можете думать об HANDLE как об экземпляре класса без методов, состояние которого может быть изменено только другими функциями. В этом случае функция ShowWindow изменяет состояние РУЧКИ окна.

См. Дескрипторы и типы данных для получения дополнительной информации.

34
ответ дан 23 November 2019 в 22:35
поделиться

Дескриптор - это уникальный идентификатор объекта, управляемого Windows. Это как указатель , но не указатель в том смысле, что это не адрес, который может быть разыменован кодом пользователя для получения доступа к некоторым данным.Вместо этого дескриптор должен быть передан в набор функций, которые могут выполнять действия с объектом, который идентифицируется дескриптором.

8
ответ дан 23 November 2019 в 22:35
поделиться

Итак, на самом базовом уровне РУЧКА любого вида указатель на указатель или

#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 до:

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

Есть вероятность, что printf напечатает обновленное значение 2. Но есть также вероятность, что foo вызовет некоторые форма повреждения памяти или исключения.

Причина в том, что, хотя вы сейчас используете указатель для передачи obj функции, которую вы также выделяете 2 мегабайта памяти, это может привести к тому, что ОС будет перемещать память вокруг обновления местоположения объект Поскольку вы передали указатель по значению,

4
ответ дан 23 November 2019 в 22:35
поделиться

Подумайте об окне в Windows как о структуре, которая его описывает. Эта структура является внутренней частью Windows, и вам не нужно знать ее подробности. Вместо этого Windows предоставляет typedef для указателя на структуру для этой структуры. Это «ручка», за которую можно схватиться за окно.,

2
ответ дан 23 November 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: