Как условно выполнить функцию, если операционная система ее поддерживает? - PullRequest
2 голосов
/ 26 января 2012

Я хотел бы создать приложение, которое вызывает CancelIoEx в Windows Vista и новее (где это поддерживается) и выполняет что-то еще в Windows XP (где это не так).

  1. Что произойдет, если я скомпилирую приложение под Windows 7, но запусту его под Windows XP? Что будет происходить во время выполнения? Получу ли я какую-то ошибку при загрузке?

  2. Как заставить мое приложение выбирать тот или иной путь к коду (избегая ошибок загрузки) в зависимости от того, какая операционная система используется во время выполнения? Пожалуйста, предоставьте образец кода.

ОБНОВЛЕНИЕ : Обратите внимание, что DLL существует в Windows XP, но функция не существует.

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Да, приложение, которое ссылается на несуществующий экспорт DLL, не сможет загрузиться.

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

Вместо этого вам необходимо разрешить ссылку во время выполнения.

Один из вариантов - импорт с отложенной загрузкой (с флагом компоновщика /DELAYLOAD), ноЯ не думаю, что это поддерживается для основных системных библиотек DLL (например, kernel32).

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

// Declare type of pointer to CancelIoEx function
typedef BOOL (WINAPI *CancelIoExType)(HANDLE hFile, LPOVERLAPPED lpOverlapped);

// Load module; won't fail because it's already imported
HMODULE hKernel32 = LoadLibrary(L"kernel32.dll");
// Look up function address
CancelIoExType pCancelIoEx = (CancelIoExType)GetProcAddress(hKernel32, "CancelIoEx");
// Do something with it
if (pCancelIoEx)
{
    // Function exists so call it
    pCancelIoEx(hMyFile, pMyOverlapped);
}
else
{
    // Function doesn't exist
}
1 голос
/ 26 января 2012

Чтобы разрешить символ во время выполнения, вам необходимо использовать LoadLibrary и GetProcAddress:

HMODULE kernel32 = LoadLibrary("kernel32.dll");
BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED) = GetProcAddress(kernel32, "CancelIoEx");

В случае, если CancelIoEx недоступен, вы получите NULL обратно от GetProcAddress. Если у вас есть указатель (вам нужно сделать это только один раз), вы можете вызвать его как обычно:

pCancelIoEx(h, &lp);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...