在运行时获取DLL路径

Yoc*_*mer 55 c++ dll

我想从其代码中获取dll的目录(或文件)路径.(不是程序的.exe文件路径)

我尝试了一些我发现的方法:
GetCurrentDir- 获取当前目录路径.
GetModuleFileName - 获取可执行文件的路径.

那么如何才能找到代码所在的dll?
我正在寻找类似于C#的东西Assembly.GetExecutingAssembly

mka*_*aes 95

您可以使用该GetModuleHandleEx函数并获取DLL中静态函数的句柄.你会在这里找到更多信息.

之后,您可以使用GetModuleFileName从刚刚获得的句柄获取路径.对呼叫的更多信息,点击这里.

一个完整的例子:

char path[MAX_PATH];
HMODULE hm = NULL;

if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
        (LPCSTR) &functionInThisDll, &hm) == 0)
{
    int ret = GetLastError();
    fprintf(stderr, "GetModuleHandle failed, error = %d\n", ret);
    // Return or however you want to handle an error.
}
if (GetModuleFileName(hm, path, sizeof(path)) == 0)
{
    int ret = GetLastError();
    fprintf(stderr, "GetModuleFileName failed, error = %d\n", ret);
    // Return or however you want to handle an error.
}

// The path variable should now contain the full filepath for this DLL.
Run Code Online (Sandbox Code Playgroud)

  • [PathRemoveFileSpec](http://msdn.microsoft.com/en-us/library/bb773748(VS.85).aspx)也是你的朋友. (3认同)
  • 好答案!比接受的答案稳定得多. (2认同)
  • 值得注意的是,在存在"GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS"标志的情况下,`lpModuleName`可能不仅仅是本地函数.它也可能是**(本地)静态变量**的地址. (2认同)

cpr*_*mer 35

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
Run Code Online (Sandbox Code Playgroud)

....

WCHAR   DllPath[MAX_PATH] = {0};
GetModuleFileNameW((HINSTANCE)&__ImageBase, DllPath, _countof(DllPath));
Run Code Online (Sandbox Code Playgroud)

  • 有关`__ImageBase`变量的未来兼容性的任何评论? (3认同)
  • 为什么不使用你在 DllMain 中得到的而不是 __ImageBase ? (2认同)

Rem*_*eau 17

GetModuleFileName()从DLL的代码内部工作正常.请确保不要将第一个参数设置为NULL,因为这将获得调用进程的文件名.您需要指定DLL的实际模块实例.你可以将它作为DLL DllEntryPoint()函数中的输入参数,只需将其保存到某个地方的变量中,以便以后在需要时使用.

  • GetModuleHandle 将为您提供与 DllEntryMain 的输入参数相同的句柄。 (2认同)

Buv*_*inJ 5

这是投票最高答案的 Unicode 修订版:

CStringW thisDllDirPath()
{
    CStringW thisPath = L"";
    WCHAR path[MAX_PATH];
    HMODULE hm;
    if( GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
                            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                            (LPWSTR) &thisDllDirPath, &hm ) )
    {
        GetModuleFileNameW( hm, path, MAX_PATH );
        PathRemoveFileSpecW( path );
        thisPath = CStringW( path );
        if( !thisPath.IsEmpty() && 
            thisPath.GetAt( thisPath.GetLength()-1 ) != '\\' ) 
            thisPath += L"\\";
    }
    else if( _DEBUG ) std::wcout << L"GetModuleHandle Error: " << GetLastError() << std::endl;
    
    if( _DEBUG ) std::wcout << L"thisDllDirPath: [" << CStringW::PCXSTR( thisPath ) << L"]" << std::endl;       
    return thisPath;
}
Run Code Online (Sandbox Code Playgroud)