讲师中心 微信公众号
AI工具推荐 视频效率加速

c++如何获取执行文件的当前路径_c++跨平台路径获取【实战】

胖涛同学_6519

胖涛同学_6519

发布时间:2026-02-13 10:09:12

|

732人浏览过

|

来源于php中文网

原创

GetModuleFileNameA(Windows)、/proc/self/exe(Linux)、_NSGetExecutablePath(macOS)是获取可执行文件真实路径的可靠方式,应配合std::filesystem::canonical标准化处理,避免依赖argv[0]或GetCurrentDirectoryA。

c++如何获取执行文件的当前路径_c++跨平台路径获取【实战】

Windows 下用 GetModuleFileNameA 获取可执行文件路径

在 Windows 上,GetModuleFileNameA 是最直接可靠的方式——它不依赖当前工作目录,而是从 PE 加载器中读取真实加载路径。传入 NULL 作为第一个参数时,它返回当前进程主模块(即 .exe)的完整路径。

常见错误是传错参数:第二个参数必须是足够大的缓冲区(比如 MAX_PATH 字节),第三个参数是缓冲区大小(不是字符串长度),且调用后需手动加 \0(如果返回值等于缓冲区大小,说明可能被截断)。

  • 务必检查返回值是否为 0(失败)或 ≥ MAX_PATH(可能截断)
  • 路径含反斜杠 \,若后续要拼接子路径,建议统一转成正斜杠或用 std::filesystem::path 处理
  • 不要用 GetCurrentDirectoryA 替代——它返回的是启动时的工作目录,不是 exe 所在目录

Linux/macOS 下用 /proc/self/exe 或 _NSGetExecutablePath

Linux 通过符号链接 /proc/self/exe 指向当前可执行文件的真实路径(即使被重命名或移动过也会解析到原文件)。用 readlink 读取即可。macOS 不支持 /proc,得用 _NSGetExecutablePath(仅限 macOS,需链接 -framework Foundation)。

注意:readlink 返回值是实际写入字节数,不自动补 \0;而 _NSGetExecutablePath 要求传入缓冲区大小指针,且可能返回 int 错误码(如缓冲区太小会返回 -1 并把所需大小写入指针)。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • Linux 示例:用 std::vector<char> buf(PATH_MAX)</char> 分配缓冲区,再调用 readlink("/proc/self/exe", buf.data(), buf.size()-1)
  • macOS 下若 _NSGetExecutablePath 返回 -1,需先调用一次获取所需大小,再重新分配内存调用
  • 两种方式都可能返回相对路径(极少见,多见于某些容器或沙箱环境),建议用 realpath() 标准化

用 std::filesystem::canonical 统一处理路径(C++17)

跨平台项目里,拿到原始路径后别急着字符串拼接。用 std::filesystem::path 构造,再调用 std::filesystem::canonical 可解决符号链接、..、软链接等歧义,得到绝对、规范、可移植的路径。

但要注意:canonical 要求路径存在且可访问,如果 exe 被卸载或权限不足,会抛 std::filesystem::filesystem_error。生产环境应捕获并 fallback 到原始路径。

  • 构造 std::filesystem::path 时,原始字符串中的反斜杠会被自动转义,推荐用原始字符串字面量或正斜杠
  • 若只需目录部分,用 .parent_path(),不要用 find_last_of 手动截断
  • 避免在路径中混用 std::string 拼接和 std::filesystem::path——类型不一致易出错

为什么不能只靠 argv[0]?

argv[0] 看似简单,但它只是启动时传入的程序名,可能为相对路径、无路径前缀(如只写了 ./myapp 或 myapp),甚至被恶意篡改。在服务化场景(systemd、supervisor 启动)或 shell 封装脚本中,argv[0] 常常完全不可信。

实测中,Linux 下用 exec -a "fake" ./myapp 启动后,argv[0] 就是 fake,与真实路径毫无关系。

  • 仅当明确控制启动方式且无需强可靠性时,才考虑用 argv[0] + std::filesystem::absolute fallback
  • 永远不要对 argv[0] 做 substr 或 find_last_of 截取目录——它可能根本不含 /
  • 某些嵌入式或精简环境(如 musl + busybox)可能连 /proc/self/exe 都不可用,此时只能接受降级策略

真正麻烦的不是“怎么拿路径”,而是“拿到之后怎么安全地拼配置文件、资源目录”。路径分隔符、大小写敏感性、符号链接循环、挂载点变更——这些细节在开发机上不出问题,上线后才突然暴露。建议所有路径操作都包裹在 std::filesystem 接口里,别自己写 str.replace。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6959

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1838

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2944

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6244

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6129

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

7714

2024.03.22

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

0

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn