почему нам не нужно закрывать дескриптор, возвращаемый ShellExecute? - PullRequest
5 голосов
/ 06 мая 2010

В случае успеха ShellExecute возвращает дескриптор.

Нужно ли закрывать эту ручку, и если да, то как?

Согласно опубликованным примерам моего Microsoft, нам нужно не закрыть этот дескриптор. Но документ ShellExecute сам по себе не обсуждается. Можете ли вы подтвердить, что нам действительно не нужно закрывать эту ручку?

Но тогда, как дескриптор может быть действительным и не нуждается в закрытии ??? Какое из следующих утверждений является / является верным:

  1. дескриптор недействителен, и мы ничего не можем с ним сделать;
  2. дескриптор никогда не освобождается, и происходит (при поддержке Microsoft) утечка памяти (до завершения программы вызывающей стороны);
  3. дескриптор автоматически освобождается системой через некоторое время и впоследствии никогда не используется повторно (-> другой тип утечки ресурса). Только при попытке использовать его мы можем узнать, указывает ли оно на что-то еще.
  4. что еще?

Ответы [ 3 ]

4 голосов
/ 06 мая 2010

Это hinstance - это 16-битная вещь , в win32 это просто число> 32 в случае успеха и не может использоваться ни для чего, кроме как в качестве кода ошибки, когда происходит сбой функции. С другой стороны, если вы передадите SEE_MASK_NOCLOSEPROCESS в версию Ex, у вас есть дескриптор, который нужно закрыть.

4 голосов
/ 06 мая 2010

Взято из: http://msdn.microsoft.com/en-us/library/bb762153%28VS.85%29.aspx

Если функция завершается успешно, она возвращает значение больше 32. Если функция терпит неудачу, он возвращает значение ошибки, которое указывает на причину сбоя. Возвращаемое значение приведено как HINSTANCE для обратной совместимости с 16-разрядными приложениями Windows. It однако, это не настоящее HINSTANCE . Это может быть приведен только к int и по сравнению с 32 или ниже коды ошибок ниже.

0 голосов
/ 13 мая 2010

Я немного понимаю, что такое HINSTANCE и HMODULE. Это не HANDLE, а скорее адрес памяти (указатель). Вы можете понять это, если просто приведете hInstance к (IMAGE_DOS_HEADER *) и загляните внутрь загруженного модуля. Вы можете использовать VirtualQueryEx (GetCurrentProcess(),...) для получения дополнительной информации (например, размера) с адреса памяти.

Посмотрите на http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx и http://www.apriorit.com/our-experience/articles/9-sd-articles/74-hmodule-hinstance-handle-from-static-library-in-c, и вы увидите, как можно получить HINSTANCE с адреса памяти (__ImageBase).

Так, если вы, например, LoadLibrary, вы получите HMODULE (это то же самое, что и HINSTANCE). Вы должны использовать FreeLibrary не для «закрытия дескриптора», а для выгрузки модуля из памяти. Например, если вы используете GetModuleHandle, вы также получаете тот же адрес (вы получаете адрес, переведенный как HMODULE), но вам НЕ следует звонить FreeLibrary, чтобы "закрыть дескриптор".

Если вы понимаете, что такое HINSTANCE и HMODULE и как их следует использовать, вы узнаете, как использовать HINSTANCE, возвращенное с ShellExecute.

...