如何根据windows版本正确加载GetMappedFileName
How to load GetMappedFileName correctly based on windows version
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上的Kernel32.dll;Psapi.dll(如果PSAPI_VERSION=1)在Windows 7和Windows Server 2008 R2上;上的Psapi.dllWindows Server 2008、Windows Vista、Windows Server 2003和WindowsXP
并没有让我们更清楚地了解windows版本是如何与PSAPI版本精确协调的。
GetMappedFileName()
文档特别指出:
从Windows7和WindowsServer2008R2开始,Psapi.h为Psapi函数建立版本号PSAPI版本号影响用于调用函数的名称以及程序必须加载的库。
如果PSAPI_VERSION为2或更大,则此函数在PSAPI.h中定义为K32GetMappedFileName,并在Kernel32.lib和Kernel32.dll中导出。如果PSAPI_VERSION为1,则此功能在PSAPI.h中定义为GetMappedFileNName,并在PSAPI.lib和PSAPI.dll中导出为调用K32GetMappedFileName的包装器。
必须在早期版本的Windows以及Windows 7及更高版本上运行的程序应始终将此函数调用为GetMappedFileName。为了确保符号的正确分辨率,请将Psapi.lib添加到TARGETLIBS宏中,并使用-DSAPI_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);
或者,按照文档所说的去做——完全忽略kernel32,在所有Windows版本上单独使用psapi.dll。在Windows7及更高版本上,psapi.GetMappedFileNameW()
是kernel32.K32GetMappedFileNameW()
的包装器。
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);
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 使用 SDL2 和SDL_image C++加载图像
- 无法使用加载库卸载注入的 dll (C++)
- 是否有原子加载非原子值的函数?
- 将 bmp 文件加载到 TSpeedButton 中
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- 加载与引用 .NET DLL 位于同一文件夹中的引用的 .NET DLL 时"Not found"异常