我想读取我的DLL的加载器DLL的二进制文件。但是有一个exe和2 DLL我使用第一个(X DLL)loadind第二个(Y DLL)。当我通过exe从X DLL加载Y dll时,GetModuleFileNameA(NULL, szEXEPath, 2048);
函数只给我一个exe路径。我想获得X DLL路径。我可以使用GetModuleFileNameA("X DLL Name", szEXEPath, 2048);
,但我不知道X DLL的名称。
当我阅读GetModuleFileName
的MSDN帮助时,我在下面看到了关于函数的第一个参数的描述。
正在请求路径的已加载模块的句柄。如果这 参数为
NULL
,GetModuleFileName
检索路径 当前进程的可执行文件。
我不想获得可执行文件的路径,我只是想确定哪个DLL加载我当前的DLL。有没有办法找到加载器路径DLL?
答案 0 :(得分:1)
获得"父母"在dll的名称中,您可以创建一个函数作为需要调用的API的一部分,它传递父dll的HMODULE
句柄。
将get_current_module_handle()
函数创建为inline
并将其包装到某种宏中将简化客户端代码的过程。
//... control header
inline HMODULE get_current_module_handle() {/*...*/}
#define PARENT_MODULE get_current_module_handle()
void SetControlParent(HMODULE parent);
//... client code to initialise the "parent"
SetControlParent(PARENT_MODULE);
要获取dll名称(在子项中),您可以使用GetModuleFileNameEx
和GetModuleHandleEx
函数的组合。诀窍在于GetModuleHandleEx
函数,它允许通过指向函数的指针(即dll中的函数)获取模块句柄;特别是使用标志GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
。
以下内容是某些代码的代码片段应该可以解决问题;
HMODULE get_current_module_handle()
{
HMODULE moduleHandle = NULL;
if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)get_current_module_handle, &moduleHandle))
throw std::runtime_error("unable to get the module handle");
return moduleHandle;
}
std::basic_string<TCHAR> get_module_name(HMODULE moduleHandle)
{
std::vector<TCHAR> filename(2048, _T('?')); // allocate some space
DWORD filenameLength = ::GetModuleFileNameEx(::GetCurrentProcess(), moduleHandle, &filename.front(), filename.size());
if (filenameLength && filenameLength < filename.size()) {
return std::basic_string<TCHAR>(&filename.front(), filenameLength);
}
return std::basic_string<TCHAR>(_T("unknown"));
}
//...
std::basic_string<TCHAR> dllname = get_module_name(get_current_module_handle()); // current dll
std::basic_string<TCHAR> parentdllname = get_module_name(parentHModule); // for "parent" dll
注意,上面复制了一个简化版本(基于OP中的2048长度)。还提供了用于考虑长文件名的递归实现(检查编辑)。
dllname
将是模块的完全限定路径,因此获取基本文件名,_splitpath
等函数。或者,您可以直接在上面的代码中使用GetModuleBaseName
。
std::basic_string<TCHAR> get_module_name(HMODULE moduleHandle)
{
std::vector<TCHAR> filename(MAX_PATH, _T('?')); // MAX_PATH is 260
DWORD filenameLength = ::GetModuleBaseName(::GetCurrentProcess(), moduleHandle, &filename.front(), filename.size());
if (filenameLength && filenameLength < filename.size()) {
return std::basic_string<TCHAR>(&filename.front(), filenameLength);
}
return std::basic_string<TCHAR>(_T("unknown"));
}
答案 1 :(得分:0)
您可以使用dllpath函数定义自己的路径,并将其作为参数传递给链接的路径。