C++編程實(shí)現(xiàn)獲取當(dāng)前可執(zhí)行文件名稱
一、介紹
在C++開發(fā)中,有時(shí)需要獲取當(dāng)前可執(zhí)行文件的名稱用來(lái)處理一些事務(wù)。那么,在主流的平臺(tái)上,獲取當(dāng)前可執(zhí)行文件名稱的方法有哪些呢?一般來(lái)說(shuō),無(wú)論哪個(gè)平臺(tái)下都分為以下幾類:
- 使用接口
- 使用配置文件或相關(guān)屬性(注冊(cè)表等)
- 使用第三方庫(kù)
下面將分別在Windows和Linux兩大主流平臺(tái)上進(jìn)行分析說(shuō)明。
二、Windows平臺(tái)
按照上面的三類劃分,在Windows平臺(tái)上獲取可執(zhí)行文件名稱的方法有:
1.系統(tǒng)接口
1)使用GetModuleFileName函數(shù),這是在Windows平臺(tái)上推薦的用法:
#include <windows.h>
#include <iostream>
#include <string>
int main() {
char exePath[MAX_PATH];
DWORD len = GetModuleFileNameA(NULL, exePath, MAX_PATH);
if (len == 0) {
std::cerr << "err code: " << GetLastError() << std::endl;
return 1;
}
std::string fullPath(exePath);
std::cout << "cur full path: " << fullPath << std::endl;
return 0;
}
2)使用C提供的_get_pgmptr函數(shù)來(lái)獲取_pgmptr
#include <cstdlib>
#include <iostream>
int main() {
char* pgmptr = nullptr;
errno_t err = _get_pgmptr(&pgmptr);
if (pgmptr != nullptr) {
std::cout << "full path: " << pgmptr << std::endl;
}
return 0;
}2.配置文件及相關(guān)
- 直接讀取main函數(shù)中的argv[0],它一般只包括名字而不包括完整路徑。這個(gè)簡(jiǎn)單就不舉例了。
- 讀取環(huán)境變量或配置文件(這需要程序中做一些特殊的輸出或配置,普通的可執(zhí)行文件可能無(wú)法應(yīng)用)
3.第三方庫(kù)
在Windows平臺(tái)上有很多的第三方框架或庫(kù)都提供了類似的機(jī)制,如boost::dll::program_location()等。例程看后面。
三、Linux平臺(tái)
Linux平臺(tái)亦是如此,但是它的實(shí)現(xiàn)方式更加豐富:
1.系統(tǒng)接口
使用dladdr
#include <iostream>
#include <dlfcn.h>
int main() {
Dl_info dl;
if (dladdr((void*)main, &dl) && dl.dli_fname) {
std::cout << "path: " << dl.dli_fname << std::endl;
}
return 0;
}
其它平臺(tái)一些變種:如Solaris中的getexecname()接口等
2.配置文件及相關(guān)
讀取/proc/self/exe鏈接,獲取當(dāng)前可執(zhí)行文件名稱
#include <iostream>
#include <unistd.h>
#include <limits.h>
int main() {
char exePath[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
if (len != -1) {
exePath[len] = '\0';
std::cout << "full path: " << exePath << std::endl;
}
return 0;
}
讀取/proc/self/cmdline
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream cmdline("/proc/self/cmdline");
if (cmdline.is_open()) {
std::string exePath;
std::getline(cmdline, exePath, '\0');
std::cout << "full path: " << exePath << std::endl;
}
return 0;
}
使用main函數(shù)中的argv[0],不贅述
gunlib中的program_name
這個(gè)需要主動(dòng)初始化,有點(diǎn)類似Windows平臺(tái)的特殊配置
3.第三庫(kù)
1)典型的就是使用Boost庫(kù)中的boost::dll::program_location(),看例子:
#include <iostream>
#include <boost/dll/runtime_symbol_info.hpp>
int main() {
boost::dll::fs::path fullPath = boost::dll::program_location();
std::cout << "full path: " << fullPath.string() << std::endl;
return 0;
}
2)其它一些特定系統(tǒng)上的庫(kù)如libbsd等
四、分析說(shuō)明
除了上面的分析的方法外,另外還可以使用一些特殊的技巧來(lái)獲取執(zhí)行文件的名稱,比如使用調(diào)試的接口(backstarce函數(shù))等等。
通過(guò)上面的分析說(shuō)明,基本上可以看到它們的優(yōu)缺點(diǎn)。
對(duì)使用接口操作來(lái)說(shuō),優(yōu)點(diǎn)是安全穩(wěn)定及準(zhǔn)確,但可能無(wú)法跨平臺(tái)。而且可能有的平臺(tái)上需要安裝一些特定的庫(kù);
一般來(lái)說(shuō),使用配置及相關(guān)的方法,相對(duì)來(lái)說(shuō)都比較準(zhǔn)確,通常包括完整的全路徑。但缺點(diǎn)是依賴于特定的平臺(tái)或系統(tǒng),而且有可能還需要權(quán)限。這點(diǎn)就限制了不少的應(yīng)用,特別是在某些裁剪的系統(tǒng)上的應(yīng)用;
使用第三方庫(kù)的優(yōu)點(diǎn)是應(yīng)用上簡(jiǎn)單,靈活多變。缺點(diǎn)是需要安裝第三方庫(kù)而且在編譯時(shí)需要增加對(duì)相關(guān)的庫(kù)的鏈接。對(duì)于一些小的工程就不太實(shí)用了。
這里必須單獨(dú)把使用argv[0]拿出來(lái),它作為一種很傳統(tǒng)的獲取可執(zhí)行文件名稱的方法,在正式場(chǎng)景下不建議使用。因?yàn)橛绊懰囊蛩乇容^多,有可能名稱根本就不對(duì)。所以還是要引起注意。
五、總結(jié)
其實(shí)在真正的應(yīng)用中,這種小功能的需求層出不窮。真正和用戶打過(guò)交道的開發(fā)者就會(huì)明白,用戶有時(shí)候想得非常“野”,讓開發(fā)者有一種應(yīng)接不暇的感覺。其實(shí)換位思考,誰(shuí)都想讓軟件的應(yīng)用更方便快捷。一個(gè)小功能往往就會(huì)讓用戶感到軟件的人性化。
以上就是C++編程實(shí)現(xiàn)獲取當(dāng)前可執(zhí)行文件名稱的詳細(xì)內(nèi)容,更多關(guān)于C++獲取當(dāng)前可執(zhí)行文件名稱的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
LeetCode 單調(diào)棧內(nèi)容小結(jié)
這篇文章主要介紹了LeetCode 單調(diào)棧內(nèi)容小結(jié),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言中結(jié)構(gòu)體(struct)的幾種初始化方法
相信大家都知道struct結(jié)構(gòu)體是C語(yǔ)言中非常重要的復(fù)合類型,初始化的方法很多,那么小編下面對(duì)這些方法進(jìn)行總結(jié),便于自己和大家以后查閱,有需要的可以參考借鑒。2016-08-08
利用Qt實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)報(bào)文大小端數(shù)據(jù)的收發(fā)
大小端(Endianness)是計(jì)算機(jī)體系結(jié)構(gòu)的一個(gè)術(shù)語(yǔ),它描述了多字節(jié)數(shù)據(jù)在內(nèi)存中的存儲(chǔ)順序,下面我們來(lái)看看如何利用Qt實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)報(bào)文大小端數(shù)據(jù)的收發(fā)吧2024-11-11
C語(yǔ)言函數(shù)傳遞數(shù)組和傳遞地址的區(qū)別你知道嗎
這篇文章主要介紹了C語(yǔ)言中數(shù)組作為函數(shù)的參數(shù)以及返回值的使用簡(jiǎn)單入門,這里以一維數(shù)組作為基本條件進(jìn)行例子講解,需要的朋友可以參考下2021-09-09
C++構(gòu)建緩存加速的實(shí)現(xiàn)示例
本文主要介紹了C++構(gòu)建緩存加速的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-10-10
C語(yǔ)言數(shù)據(jù)的存儲(chǔ)專項(xiàng)分析
使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么2022-07-07

