C++ 如何基于windows版本正确加载GetMappedFileName

C++ 如何基于windows版本正确加载GetMappedFileName,c++,windows,winapi,windows-7,windows-xp,C++,Windows,Winapi,Windows 7,Windows Xp,MSDN的备注部分特别提到以下函数的加载类型之间存在差异 由于我的模块是可移植的,可以动态加载模型,因此不允许/无法使用任何预处理器命令: #if (PSAPI_VERSION == 2) (GetProcAddress("kernel32.dll", OBFUSCATE(L"K32GetMappedFileNameW"))); #elif (PSAPI_VERSION == 1) (GetProcAddress("psapi.dll", OBFU

MSDN的备注部分特别提到以下函数的加载类型之间存在差异

由于我的模块是可移植的,可以动态加载模型,因此不允许/无法使用任何预处理器命令:

#if (PSAPI_VERSION == 2)
            (GetProcAddress("kernel32.dll", OBFUSCATE(L"K32GetMappedFileNameW")));
#elif (PSAPI_VERSION == 1)
            (GetProcAddress("psapi.dll", OBFUSCATE(L"GetMappedFileNameW")));
#endif
此外—

Windows 7和Windows Server 2008 R2上的内核32.dll;Psapi.dll(如果 Windows7和WindowsServer2008R2上的PSAPI_版本=1);上的Psapi.dll Windows Server 2008、Windows Vista、Windows Server 2003和Windows XP

这并没有使windows版本与PSAPI版本之间的协调变得更加清晰

报告明确指出:

从Windows7和WindowsServer2008R2开始,Psapi.h为Psapi函数建立版本号PSAPI版本号影响用于调用函数和程序必须加载的库的名称

如果PSAPI_版本为2或更高,则此函数在PSAPI.h中定义为K32GetMappedFileName,并在Kernel32.lib和Kernel32.dll中导出。如果PSAPI_VERSION为1,则此函数在PSAPI.h中定义为GetMappedFileName,并在PSAPI.lib和PSAPI.dll中导出为调用K32GetMappedFileName的包装器

必须在早期版本的Windows以及Windows 7和更高版本上运行的程序应始终将此函数称为GetMappedFileName。为确保符号的正确分辨率,请将Psapi.lib添加到TARGETLIBS宏,并使用-DPSAPI_VERSION=1编译程序。要使用运行时动态链接,请加载Psapi.dll。

如果静态链接不是您的选项,并且您需要在运行时动态加载函数而不使用
#ifdef
语句,那么只需无条件地检查两个DLL,例如:

typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);

HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL; 

...

lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(GetModuleHandle("kernel32.dll"), L"K32GetMappedFileNameW"));
if (lpGetMappedFileNameW == NULL)
{
    hPsapi = LoadLibraryW(L"psapi.dll");
    lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");
}

// use lpGetMappedFileNameW() as needed ...

if (hPsapi)
    FreeLibrary(hPsapi);
或者,按照文档所说的去做——完全忽略内核32,在所有Windows版本上单独使用psapi.dll。在Windows 7及更高版本上,
psapi.GetMappedFileNameW()
kernel32.K32GetMappedFileNameW()的包装

下一段:“必须在Windows早期版本以及Windows 7和更高版本上运行的程序应始终将此函数称为GetMappedFileName。”
typedef DWORD WINAPI (*LPFN_GetMappedFileNameW)(HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize);

HINSTANCE hPsapi = NULL;
LPFN_GetMappedFileNameW lpGetMappedFileNameW = NULL;

...

hPsapi = LoadLibraryW(L"psapi.dll");
lpGetMappedFileNameW = (LPFN_GetMappedFileNameW) GetProcAddress(hPsapi, L"GetMappedFileNameW");

// use lpGetMappedFileNameW() as needed ...

FreeLibrary(hPsapi);