in concrete case InterlockedIncrementNoFence64
not imported from any dll but implemented using a compiler intrinsic on most platform (x86 - via _InterlockedCompareExchange64
, amd64 - _InterlockedIncrement64
, arm/arm64 - _InterlockedIncrement64_nf
). so code with this concrete call will be work on any windows version (in win7 as well of course).
in more general case, if we need use several functions, which is not exported on all os - we can declare it as function pointer and resolve in run-time. for example let take LoadPackagedLibrary
api
we can declare function pointer:
HMODULE (WINAPI * LoadPackagedLibraryAddr)(
_In_ LPCWSTR lpwLibFileName,
_Reserved_ DWORD Reserved
);
resolve it in run-time:
*(void**)&LoadPackagedLibraryAddr = GetProcAddress(
GetModuleHandleW(L"kernel32"), "LoadPackagedLibrary");
and use:
if (LoadPackagedLibraryAddr)
{
LoadPackagedLibraryAddr(L"***",0);
}
else {...}
another possible way for function declared with __declspec(dllimport)
(most windows api declared with this prefix) use next syntax:
extern "C" {
PVOID __imp_LoadPackagedLibrary;
}
#ifdef _M_IX86
__pragma(comment(linker, "/alternatename:__imp__LoadPackagedLibrary@8=___imp_LoadPackagedLibrary"))
#endif
__imp_LoadPackagedLibrary = GetProcAddress(
GetModuleHandleW(L"kernel32"), "LoadPackagedLibrary");
#pragma warning(disable : 4551)
if (LoadPackagedLibrary)//if (__imp_LoadPackagedLibrary)
{
LoadPackagedLibrary(L"***",0);
}
however both ways generate absolute same binary code, only use different syntax.
note that not need query windows version at all, need simply try get pointer to api. or we get it and can use, or no.
the way with __declspec(selectany)
or #pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")
will be not work here because with this we resolve symbols at link time (result will be common for all windows version), but we actually need resolve symbol at run-time.