天天看點

c/c++擷取可執行程式的絕對路徑(Linux、Windows)

     今天改動一個程式,需要在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路徑執行,得到結果:

c/c++擷取可執行程式的絕對路徑(Linux、Windows)

若是在/home路徑執行,得到結果:

c/c++擷取可執行程式的絕對路徑(Linux、Windows)

補充:

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/c++擷取可執行程式的絕對路徑(Linux、Windows)

若是在C:\program執行,輸出:

c/c++擷取可執行程式的絕對路徑(Linux、Windows)

******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的路徑:

c/c++擷取可執行程式的絕對路徑(Linux、Windows)

繼續閱讀