分享
 
 
 

Linux下GetModuleFileName的四种写法

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Linux下GetModuleFileName的四种写法

问题的起因是要把一个东东从Windows移植到基于Linux的嵌入式系统上。移植过程中,遇到了GetModuleFileName的问题。为了解决这个问题,花了不少的时间,也走了不少弯路。下面是整理的结果。

首先摘录一段文字,来源《UNIX Programming FAQ 中文版》

1.14. 我怎样找到进程的相应可执行文件?

这个问题可以作为'常见未回答问题'('Frequently Unanswered Questions')的一个好候选,因为事实上提出这个问题经常意味着程序的设计有缺陷。:)

你能作的'最佳猜测'('best guess')是通过审视'argv[0]'的值而获得。如果它包括一个'/',那么它可能是可执行程序的绝对或相对(对于在程序开始时的当前目录而言)路径。如果不包括,那么你可以仿效shell对于'PATH'变量的查询来查找这个程序。但是,不能保证成功,因为有可能执行程序时'argv[0]'是一些任意值,也不排除这个可执行文件在执行后可能已经被更名或删除的情况。

如果所有你想做的只是能打印一个和错误消息一起出现的合适的名字,那么最好的方法在'main()'函数中将'argv[0]'的值保存在全局变量中以供整个程序使用。虽然没有保证说'argv[0]'的值总是有意义,但在大多数情况下它是最好的选择。

人们询问这个问题的最普通原因是意图定位他们程序的配置文件。这被认为是不好的形式;包含可执行文件的目录应当*只*包含可执行文件,而且基于管理的要求经常试图将配置文件放置在和可执行文件不同的文件系统。

试图做这个的一个比较不普通但更正规的理由是允许程序调用'exec()'执行它自己;这是一种用来完全重新初始化进程(比如被用于一些'sendmail'的版本)的办法(比如当一个守护程序捕获一个'SIGHUP'信号)。

完全同意上面的观点的!所以并不建议在Linux下去实现GetModuleFileName,不过出于技术的角度,讨论一下这个问题也是可以的。

好,下面说说茴字的四种写法。哦,不,是GetModuleFileName的四种写法。

GetModuleFileName的四种写法

方法一:从PATH入手

说明:上文提供的思路

int GetModuleFileName1( char* sModuleName, char* sFileName, int nSize)

{

int ret = -1;

if( strchr( sModuleName,'/' ) != NULL )

strcpy( sFileName, sModuleName );

else

{

char* sPath = getenv("PATH");

char* pHead = sPath;

char* pTail = NULL;

while( pHead != NULL && *pHead != '\x0' )

{

pTail = strchr( pHead, ':' );

if( pTail != NULL )

{

strncpy( sFileName, pHead, pTail-pHead );

sFileName[pTail-pHead] = '\x0';

pHead = pTail+1;

}

else

{

strcpy( sFileName, pHead );

pHead = NULL;

}

int nLen = strlen(sFileName);

if( sFileName[nLen] != '/' )sFileName[nLen] = '/';

strcpy( sFileName+nLen+1,sModuleName);

if( 0 == access( sFileName, F_OK ) )

{

ret = 0;

break;

}

}

}

return ret;

}

方法二:利用which命令

说明: 与方法一相比,完全是换汤不换药,之所以放在这里,是因为其中用到了一个小技巧:即利用popen()实现在代码中执行一段command,并得到其执行的结果。

int GetModuleFileName2( char* sModuleName, char* sFileName, int nSize)

{

int ret = 0;

if( strchr( sModuleName,'/' ) != NULL )

strcpy( sFileName, sModuleName );

else

{

char sBuffer[256] = { 0, };

char sCommand[256] = { 0, };

FILE* fp = NULL;

sprintf( sCommand, "which %s", sModuleName );

if((fp = popen(sCommand,"r")) == NULL){

ret = -1;

}

else

{

sFileName[0] = '\x0';

while(!feof(fp)){

if(fgets(sBuffer,nSize-1,fp) == NULL){

continue;

}

strcat( sFileName, sBuffer );

}

}

int nLen = strlen( sFileName );

if( 0 == nLen )

ret = -1;

else

if( sFileName[nLen-1] = '\n' ) sFileName[nLen-1] = '\x0';

}

return ret;

}

方法二:获取环境变量"_"

int GetModuleFileName3( char* sModuleName, char* sFileName, int nSize)

{

int ret = -1;

char* p = getenv("_");

if( p != NULL && strstr( p, sModuleName ) != NULL )

{

ret = 0;

strcpy( sFileName, p );

}

return ret;

}

方法四:读取/proc/self/maps

说明: 细节请参阅 http://autopackage.org/docs/binreloc/

int GetModuleFileName4( char* sModuleName, char* sFileName, int nSize)

{

int ret = -1;

char sLine[1024] = { 0 };

void* pSymbol = (void*)"";

FILE *fp;

char *pPath;

fp = fopen ("/proc/self/maps", "r");

if ( fp != NULL )

{

while (!feof (fp))

{

unsigned long start, end;

if ( !fgets (sLine, sizeof (sLine), fp))

continue;

if ( !strstr (sLine, " r-xp ") || !strchr (sLine, '/'))

continue;

sscanf (sLine, "%lx-%lx ", &start, &end);

if (pSymbol >= (void *) start && pSymbol < (void *) end)

{

char *tmp;

size_t len;

/* Extract the filename; it is always an absolute path */

pPath = strchr (sLine, '/');

/* Get rid of the newline */

tmp = strrchr (pPath, '\n');

if (tmp) *tmp = 0;

/* Get rid of "(deleted)" */

//len = strlen (pPath);

//if (len > 10 && strcmp (pPath + len - 10, " (deleted)") == 0)

//{

// tmp = pPath + len - 10;

// *tmp = 0;

//}

ret = 0;

strcpy( sFileName, pPath );

}

}

fclose (fp);

}

return ret;

}

测试代码:

int main ( int argc, char** argv ) {

char buffer[256]={0};

getchar();

printf ("ModuleFileName1 is: %s\n", GetModuleFileName1( argv[0], buffer, 256)==-1?"Not found!":buffer);

printf ("ModuleFileName2 is: %s\n", GetModuleFileName2( argv[0], buffer, 256)==-1?"Not found!":buffer);

printf ("ModuleFileName3 is: %s\n", GetModuleFileName3( argv[0], buffer, 256)==-1?"Not found!":buffer);

printf ("ModuleFileName4 is: %s\n", GetModuleFileName4( argv[0], buffer, 256)==-1?"Not found!":buffer);

return 0;

}

测试结果:

正常输出结果:

ModuleFileName1 is: /home/coldcrane/bin/hello

ModuleFileName2 is: /home/coldcrane/bin/hello

ModuleFileName3 is: /home/coldcrane/bin/hello

ModuleFileName4 is: /home/coldcrane/bin/hello

程序执行时目录被移动

$ mv ~/bin ~/nib

输出结果:

ModuleFileName1 is: Not found!

ModuleFileName2 is: Not found!

ModuleFileName3 is: /home/coldcrane/bin/hello

ModuleFileName4 is: /home/coldcrane/nib/hello

程序执行时文件被改名

$ mv ~/bin/hello ~/bin/hh

输出结果:

ModuleFileName1 is: Not found!

ModuleFileName2 is: Not found!

ModuleFileName3 is: /home/coldcrane/bin/hello

ModuleFileName4 is: /home/coldcrane/bin/hh

程序执行时文件被删除

$ rm ~/bin/hello

输出结果:

ModuleFileName1 is: Not found!

ModuleFileName2 is: Not found!

ModuleFileName3 is: /home/coldcrane/bin/hello

ModuleFileName4 is: /home/coldcrane/bin/hello (deleted)

相对而言,方法四是最强的,能有的信息都有了,但依然不能解决所有的问题。当然,针对不同的环境,上面的代码还是有一定的参考价值的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有