1 C++跨平台WindowsLinux系统上获取当前可执行程序路径

跨平台获取当前可执行程序路径是C++跨平台项目中会经常使用的功能,我将这个功能简单的封装成了一个PathUtils工具类,在该类中通过GetCurrentProgramDirectory静态函数获取当前可执行程序路径,下面贴出了功能实现代码。

path_utils.h

#ifndef _PATH_UTILS_H_
#define _PATH_UTILS_H_

#include <string>

class PathUtils
{
public:
    // 得到当前程序执行路径
    static std::string GetCurrentProgramDirectory();
};

#endif // !_PATH_UTILS_H_

path_utils.cpp

#include "path_utils.h"

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)

#include<Windows.h>

#elif defined(linux) || defined(__linux)

#include <string.h>
#include <unistd.h>
#include <dlfcn.h>

#endif // WINDOWS

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
static HMODULE GetSelfModuleHandle()
{
    MEMORY_BASIC_INFORMATION mbi;
    return (
        (::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0)
        ? (HMODULE)mbi.AllocationBase : NULL
        );
}

std::string PathUtils::GetCurrentProgramDirectory()
{
    std::string strCurrentPath = "";
    char curDirector[260] = { 0 };
    GetModuleFileName(GetSelfModuleHandle(), curDirector, 260);
    strCurrentPath = curDirector;

    size_t nameStart = strCurrentPath.rfind("\\");
    strCurrentPath = strCurrentPath.substr(0, nameStart + 1);
    return strCurrentPath;
}

#elif defined(linux) || defined(__linux)
std::string PathUtils::GetCurrentProgramDirectory()
{
    std::string strCurrentPath = "";
    char szCurWorkPath[256];
    memset(szCurWorkPath, '\0', 256);
    int nRet = readlink("/proc/self/exe", szCurWorkPath, 256);
    if (nRet > 256 || nRet < 0)
    {
        return strCurrentPath;
    }

    for (int i = nRet; i > 0; i--)
    {
        if (szCurWorkPath[i] == '/' || szCurWorkPath[i] == '\\')
        {
            szCurWorkPath[i] = '\0';
            break;
        }
    }

    strCurrentPath = szCurWorkPath;

    return strCurrentPath;
}
#endif

测试代码

#include <iostream>
#include "path_utils.h"

int main()
{
    std::cout << "Path : " << PathUtils::GetCurrentProgramDirectory() << std::endl;
    return 0;
}