今天改動一個程式,需要在linux環境擷取執行程式的絕對路徑,搜尋到兩個函數,在此做下記錄和對比。
函數1:char *getcwd(char *buf, size_t size);
頭檔案:unistd.h
擷取到可執行程式的絕對路徑,存放到buf中,size是指定的buf大小。若size指定的大小比 buf短,會傳回NULL。若不知道buf的長度,可以設定size為0,則getcwd會調用malloc動态給buf配置設定空間,不過後續要記得調用free釋放buf。
不足:使用後發現,該函數傳回的是執行可執行程式的絕對路徑。
函數2:int readlink(const char * path ,char * buf,size_t bufsiz);
頭檔案:unistd.h
該将參數path的符号連接配接内容存到參數buf所指的記憶體空間,傳回的内容不是以NULL作字元串結尾。傳回值即為字段buf的長度。
若傳入的參數bufsiz小于符号連接配接的内容長度,過長的内容會被截斷。
不足:這個函數并不是直接擷取程式的絕對路徑,是通過擷取目前程式的自身資訊拿到的路徑。且得到的路徑包括了可執行程式名稱,需要再處理。
eg:在路徑/home/alex/test-getpath上寫了個測試代碼
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
char szBuf[128];
char szPath[128];
memset(szBuf, 0x00, sizeof( szBuf));
memset( szPath, 0x00, sizeof(szPath));
getcwd(szBuf, sizeof(szBuf)-1);
printf("buf:%s\n", szBuf);
int ret = readlink("/proc/self/exe", szPath, sizeof(szPath)-1 );
printf("ret:%d\n", ret);
printf("path:%s\n", szPath);
return 0;
}
若是在/home/alex/test-getpath路徑執行,得到結果:

若是在/home路徑執行,得到結果:
補充:
windows環境,有類似的替代函數。
函數1:頭檔案:#include<direct.h>
函數:char * getcwd(char * buf, size_t size);
用法類似,擷取得到的結果是執行檔案的目錄。
函數2:頭檔案:#include<windows.h>
函數:DWORD WINAPI GEtModuleFileName(
_In_opt_ HMODULE hModule, //應用程式或DLL執行個體句柄,NULL則為擷取目前程式可執行檔案路徑名
_Out_ LPTSTR lpFilename, //接收路徑的字元串緩沖區
_In_ DWORD nSize //接收路徑的字元緩沖區的大小
);
該函數類似Linux下的readlink,也會包含可執行程式名稱,需再處理去除
eg:
#include<windows.h>
#include<direct.h>
#include<stdio.h>
int main()
{
char szBuf[512] = { 0 };
getcwd(szBuf, sizeof(szBuf)-1);
printf("buf:%s\n", szBuf);
char szPath[512] = {0};
GetModuleFileName(NULL, szPath, sizeof(szPath)-1);
printf("path:%s\n", szPath);
getchar();
}
假設生成的可執行程式叫demo.exe,放在:C:\program\test目錄,
若是在 C:\program\test執行,輸出:
若是在C:\program執行,輸出:
******2020.7.6 補充******
windows環境,擷取調用動态庫的所在路徑:
eg:一個動态庫demo.dll,其中封裝了擷取動态庫的函數getPath(),一個可執行程式linkDemo.exe連結該dll,若要擷取demo.dll所在路徑,需如下實作:
/**demo.dll的内容**/
#include<windows.h>
#include<direct.h>
#include<stdio.h>
#include<tchar.h>
#include"test.h"
int getPath()
{
char szPath[512] = { 0 };
GetModuleFileName(NULL, szPath, sizeof(szPath) - 1);
printf("path:%s\n", szPath);
return 0;
}
int getLibraryPath()
{
char szPath[512] = {0};
HMODULE hMod = GetModuleHandle(_T("demo.dll"));
GetModuleFileName(hMod, szPath, sizeof(szPath)-1);
printf("path:%s\n", szPath);
return 0;
}
調用程式:
#include "test.h"
#include<stdio.h>
int main()
{
printf("begin....\n");
getLibraryPath();
getchar();
}
将linkDemo.exe放置在 C:/program/test,将demo.dll放置在E:/library中,執行可分别獲得exe和dll的路徑: