Проверка существование Windows API Functions

  • ++i увеличит значение i, и затем возвратит увеличенное значение.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++ увеличит значение i, но возвратит исходное значение, которое i содержало прежде чем быть увеличенным.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    
  • Для for цикл, любой работы. ++i кажется более распространенным, возможно, потому что, именно это используется в [1 114] K& R.

    В любом случае, следуйте, инструкция "предпочитают ++i [более чем 1 110]", и Вы не пойдете не так, как надо.

    существует несколько комментариев относительно эффективности [1 111] и i++. В любом non-student-project компиляторе не будет никакого различия в производительности. Можно проверить это путем рассмотрения сгенерированного кода, который будет идентичен.

    вопрос об эффективности интересен..., вот моя попытка ответа: там различие в производительности между мной ++ и ++ я в C?

    Как [1 116] На нотах Freund, это отличается для объекта C++, так как operator++() функция, и компилятор не может знать для оптимизации далеко создания временного объекта для содержания промежуточного значения.

6
задан Cœur 16 April 2017 в 08:52
поделиться

8 ответов

LoadLibrary и GetProcAddress будут вашими друзьями.

Также ознакомьтесь с в этом руководстве .

2
ответ дан 8 December 2019 в 18:40
поделиться

Да, вы всегда можете проверить на наличие функции в библиотеке во время выполнения и предпринять соответствующие действия. Проверьте API LoadLibrary и GetProcAddress. http://msdn.microsoft.com/en-us/library/ms683212 (VS.85) .aspx

0
ответ дан 8 December 2019 в 18:40
поделиться

Я считаю, что MSDN - ваш лучший выбор для этого. Каждая страница MSDN для документации по функциям содержит в конце раздел, в котором указано, какая версия Windows поддерживает эту функцию.

В качестве примера, проверьте документацию GetModuleHandle . Он содержит раздел с названием Требования , в котором есть поле Минимальный поддерживаемый клиент и Минимальный поддерживаемый сервер .

Однако, если вы хотите проверить наличие существование функций динамически, то вы можете сделать это с помощью LoadLibrary и GetProcAddress .

1
ответ дан 8 December 2019 в 18:40
поделиться

вы должны использовать LoadLibrary и GetProcAddress для динамической загрузки и вызова новых функций.

0
ответ дан 8 December 2019 в 18:40
поделиться

Если вы хотите узнать во время компиляции, чтобы получить прерывание сборки, если функция недоступна в целевой ОС (например, Win 95), вы можете определить некоторые макросы , задокументировано здесь : NTDDI_VERSION, _WIN32_WINNT, WINVER.

Если вы хотите, чтобы ваше приложение работало нормально, когда функциональность недоступна (например, списки переходов в ОС старше Win7), вам следует использовать комбинацию LoadLibrary / GetProcAddress, чтобы выяснить, доступна ли функция, которую вы ищете.

0
ответ дан 8 December 2019 в 18:40
поделиться

Это зависит от типов функций.

Для простых (не COM) функций единственный способ - использовать LoadLibrary и GetProcAddress . Если один из них не работает, вы знаете, что в ОС отсутствует эта функция. Написание этих объявлений типа указателя функции для указателей функций, дублирующих существующие сигнатуры функций, может быть утомительным, хотя в VC ++ 2010 вы можете использовать для этого decltype . Например:

HMODULE user32 = LoadLibraryW(L"user32");
if (user32 != NULL)
{
    auto messageBoxW = reinterpret_cast<decltype(MessageBoxW)*>(GetProcAddress(user32, "MessageBoxW"));
    if (messageBoxW != NULL)
    {
        messageBoxW(HWND_DESKTOP, L"Hello!", NULL, MB_OK);
    }
}

Однако многие API-интерфейсы Shell доступны через COM-компоненты и интерфейсы. Это разные случаи. Иногда вам нужно иметь дело с совершенно новыми компонентами; например, IApplicationDestinations - это новый интерфейс в Win7, и компонентный класс, который его реализует, также является новым. В таких случаях можно просто выполнить CoCreateInstance , и проверьте возвращаемое значение для REGDB_E_CLASSNOTREG - это означает, что такой компонентный класс не зарегистрирован в системе (и, по сути, не поддерживается).

Иногда, однако, новые версии ОС вводят новые интерфейсы на существующих коклассах. Примером является ITaskbarList3 , новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList и восходит к Win95. В таких случаях вам следует сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface для получения новых версий интерфейса и определить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE .

однако в новых версиях ОС вводятся новые интерфейсы для существующих компонентных классов. Примером является ITaskbarList3 , новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList и восходит к Win95. В таких случаях вы должны сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface для получения новых версий интерфейса и обнаружить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE .

однако в новых версиях ОС вводятся новые интерфейсы для существующих компонентных классов. Примером является ITaskbarList3 , новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList и восходит к Win95. В таких случаях вам следует сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface для получения новых версий интерфейса и определить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE .

9
ответ дан 8 December 2019 в 18:40
поделиться

Используйте LoadLibarary , чтобы получить дескриптор библиотеки и GerProcAddress для получения указателя на функцию. Для тех функций, которые не поддерживаются текущей ОС, вы получите ошибку ERROR_CALL_NOT_IMPLEMENTED из GetLastError .

0
ответ дан 8 December 2019 в 18:40
поделиться

Я не согласен с текущими решениями. В результате вы получите довольно много нечитаемого кода.

Более хорошая альтернатива - обернуть функциональность в пользовательскую DLL только для Windows 7. Для других систем предоставьте другую версию DLL, реализующую те же функции. Это часто может быть неработоспособным. Например, функция установки расширений панели задач не работает в старых версиях Windows.

Динамическое переключение между этими библиотеками DLL осуществляется с помощью функции отложенной загрузки MSVC. Вы можете использовать специальный перехватчик в вашем EXE-файле, чтобы выбрать правильную версию DLL при вызове первой функции в вашей DLL, и в этот момент вы знаете, работаете ли вы в Windows 7.

1
ответ дан 8 December 2019 в 18:40
поделиться
Другие вопросы по тегам:

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