文章

C++获取当前程序路径

C++获取当前程序路径

该文介绍 C++ 获取当前程序路径。

C++获取当前程序路径

在很多时候需要获取当前路径,来进行一些数据加载或相对路径操作。

当作为底层动态库时需要获取当前路径,结果在外部调用底层动态库库时路径是外部库的执行路径,所以这里分为两个函数

  • 获取调用获取可执行程序路径
  • 获取当前模块路径(正确获取底层库路径)

1. 获取路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strdup

#ifdef _WIN32
    #include <windows.h>
    #include <shlwapi.h> // PathRemoveFileSpec
    #pragma comment(lib, "shlwapi.lib")
#else
    #include <libgen.h> // dirname
    #include <unistd.h> // readlink
    #include <limits.h> // PATH_MAX
    #include <dlfcn.h>  // dladdr
#endif

// 获取可执行程序路径(仅目录)
char* GetExecutablePath()
{
#ifdef _WIN32
    char* buffer = (char*)malloc(MAX_PATH);
    if (buffer && GetModuleFileName(NULL, buffer, MAX_PATH))
    {
        PathRemoveFileSpec(buffer);
        return buffer;
    }
    free(buffer);
    return NULL;
#else
    char* buffer = (char*)malloc(PATH_MAX);
    if (buffer)
    {
        ssize_t len = readlink("/proc/self/exe", buffer, PATH_MAX - 1);
        if (len != -1)
        {
            buffer[len] = '\0';
            char* dir   = dirname(buffer);
            return strdup(dir);
        }
        free(buffer);
    }
    return NULL;
#endif
}

// 获取当前模块路径(仅目录)
char* GetCurrentModulePath()
{
#ifdef _WIN32
    char*   buffer  = (char*)malloc(MAX_PATH);
    HMODULE hModule = NULL;
    if (buffer && GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)GetCurrentModulePath, &hModule))
    {
        if (GetModuleFileName(hModule, buffer, MAX_PATH))
        {
            PathRemoveFileSpec(buffer);
            return buffer;
        }
    }
    free(buffer);
    return NULL;
#else
    Dl_info info;
    if (dladdr((void*)GetCurrentModulePath, &info))
    {
        char buffer[PATH_MAX] = {0};
        strncpy(buffer, info.dli_fname, PATH_MAX - 1);
        char* dir      = dirname(buffer);
        char* abs_path = realpath(dir, NULL);
        if (abs_path)
        {
            return strdup(abs_path);
        }
    }
    return NULL;
#endif
}

参考

本文由作者按照 CC BY 4.0 进行授权