是否有可能以编程方式和跨平台方式检索链接到当前进程的共享库列表(*.dll、*.so、*.dylib)?
例如:
vector<string> getLinkedSharedLibraries() {
// ...
}
vector<string> sharedLibraryList = getLinkedSharedLibraries();
for (list<string>::iterator it = sharedLibraryList.begin(); it != sharedLibraryList.end(); ++it)
cout << *it << endl;
会返回:
/usr/lib/libz.1.dylib
/usr/lib/libSystem.B.dylib
...
我正在考虑在 Linux 上使用操作系统命令,例如 ldd
和在 Mac 上使用 otool -L
,然后最终使用 [DY]LD_LIBRARY_PATH
检索那里的绝对路径。但我在 Windows 上找不到类似的方法。
或者,是否有任何现有的图书馆在做这种事情?
最佳答案
这只是 Windows 做得更好的事情之一。您不需要工具,它提供了更多信息,而且很容易检索。
“知道”特定模块是否已加载的用例并不多。要么你加载了它,要么你没有加载它。
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
#include <iostream>
#include <sstream>
bool GetModules(std::vector<MODULEENTRY32> &modules)
{
void* hSnap = nullptr;
MODULEENTRY32 Mod32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) == INVALID_HANDLE_VALUE)
return false;
Mod32.dwSize = sizeof(MODULEENTRY32);
while (Module32Next(hSnap, &Mod32))
{
modules.push_back(Mod32);
}
CloseHandle(hSnap);
return true;
}
std::string ModuleToString(MODULEENTRY32 Mod32)
{
auto to_hex_string = [](std::size_t val, std::ios_base &(*f)(std::ios_base&)) -> std::string
{
std::stringstream oss;
oss << std::hex << std::uppercase << val;
return oss.str();
};
std::string str;
str.append(" =======================================================\r\n");
str.append(" Module Name: ").append(Mod32.szModule).append("\r\n");
str.append(" =======================================================\r\n\r\n");
str.append(" Module Path: ").append(Mod32.szExePath).append("\r\n");
str.append(" Load Count (Global): ").append(std::to_string(static_cast<int>(Mod32.GlblcntUsage != 0xFFFF ? Mod32.GlblcntUsage + 1 : 0)).c_str()).append("\r\n");
str.append(" Load Count (Process): ").append(std::to_string(static_cast<int>(Mod32.ProccntUsage != 0xFFFF ? Mod32.ProccntUsage + 1 : 0)).c_str()).append("\r\n");
str.append(" Base Address: 0x").append(to_hex_string(reinterpret_cast<std::size_t>(Mod32.modBaseAddr), std::hex).c_str()).append("\r\n");
str.append(" Base Size: 0x").append(to_hex_string(Mod32.modBaseSize, std::hex).c_str()).append("\r\n\r\n");
str.append(" =======================================================\r\n");
return str;
}
int main()
{
std::vector<MODULEENTRY32> modules;
if (GetModules(modules))
{
for (auto &&it : modules)
{
std::cout<<ModuleToString(it)<<"\n";
}
}
return 0;
}
关于C++:检索共享库列表的跨平台方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28609498/