我有这个要求,我需要从内部找到C ++程序的完整路径。对于Windows,我有以下解决方案。 argv [0]可能包含也可能不包含完整路径。但我需要确定。
TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], base[_MAX_FNAME], ext[_MAX_EXT];
TCHAR fullPath[255+1];
_splitpath(argv[0],drive,dir,base,ext);
SearchPath(NULL,base,ext,255,fullPath,NULL);
上述代码的Linux(gcc)等价物是什么?很想看到可移植的代码。
答案 0 :(得分:14)
在Linux(Posix?)上,您有一个符号链接/proc/self/exe
,它链接到可执行文件的完整路径。
在Windows上,使用GetModuleFileName
。
永远不要依赖argv[0]
,这不保证是有用的。
请注意,路径和文件系统不是语言的一部分,因此必然是与平台相关的功能。
答案 1 :(得分:8)
这个问题的最佳答案列出了一大堆操作系统的技术:
答案 2 :(得分:5)
string get_path( )
{
char arg1[20];
char exepath[PATH_MAX + 1] = {0};
sprintf( arg1, "/proc/%d/exe", getpid() );
readlink( arg1, exepath, 1024 );
return string( exepath );
}
答案 3 :(得分:1)
对于Linux:
执行系统命令的功能
int syscommand(string aCommand, string & result) {
FILE * f;
if ( !(f = popen( aCommand.c_str(), "r" )) ) {
cout << "Can not open file" << endl;
return NEGATIVE_ANSWER;
}
const int BUFSIZE = 4096;
char buf[ BUFSIZE ];
if (fgets(buf,BUFSIZE,f)!=NULL) {
result = buf;
}
pclose( f );
return POSITIVE_ANSWER;
}
然后我们得到应用名称
string getBundleName () {
pid_t procpid = getpid();
stringstream toCom;
toCom << "cat /proc/" << procpid << "/comm";
string fRes="";
syscommand(toCom.str(),fRes);
size_t last_pos = fRes.find_last_not_of(" \n\r\t") + 1;
if (last_pos != string::npos) {
fRes.erase(last_pos);
}
return fRes;
}
然后我们提取申请路径
string getBundlePath () {
pid_t procpid = getpid();
string appName = getBundleName();
stringstream command;
command << "readlink /proc/" << procpid << "/exe | sed \"s/\\(\\/" << appName << "\\)$//\"";
string fRes;
syscommand(command.str(),fRes);
return fRes;
}
不要忘记在
之后修剪线条答案 4 :(得分:1)
#include <string>
#include <unistd.h>
#include <limits.h>
std::string getApplicationDirectory() {
char result[ PATH_MAX ];
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
std::string appPath = std::string( result, (count > 0) ? count : 0 );
std::size_t found = appPath.find_last_of("/\\");
return appPath.substr(0,found);
}
答案 5 :(得分:0)
如果您在谷歌搜索GetModuleFileName Linux
时来到这里...您可能正在寻找能够为动态加载的库执行此操作的功能。这是您的操作方式:
struct link_map *lm;
dlinfo(module, RTLD_DI_LINKMAP, &lm);
lm->l_name // use this