作为从HP迁移到AIX的应用程序的一部分,我面临着一个独特的问题。 以下模拟代码在HP和AIX中产生不同的结果。
library.C **
#include <stdio.h>
#include "mylib.h"
int libimgclientFNXXX()
{
int check = 100;
check = FileNetDeleteDoc(check);
return check;
}
int libimgclientFN()
{
int check = 1;
printf("In lib ");
return check;
}
* main_func.C *
#include <stdio.h>
int libimgclientFN();
int libimgclientFNXXX();
int main()
{
int one = 0;
if (1 == 1)
{
one = libimgclientFN();
}
printf("\n The status is %d \n", one);
}
* mylib.h **
extern int FileNetDeleteDoc (int);
请注意,函数libimgclientFNXXX()永远不会被调用。 我的make文件如下:
xlC -c -g library.C -o library.o -I./
xlC -G -qmkshrobj -o libImgClient.so library.o
xlC -c -g -qpic=small main_func.C -o main_func.o
xlC -brtl main_func.o -L. -lImgClient -o TST
当我运行TST时,我收到以下加载错误
$ TST
exec(): 0509-036 Cannot load program TST because of the following errors:
rtld: 0712-001 Symbol FileNetDeleteDoc__Fi was referenced
from module ./libImgClient.so(), but a runtime definition
of the symbol was not found.
即使从未调用函数libimgclientFNXXX(),也存在未解决的错误。
HP内置的完全相同的代码可以正常运行,没有任何错误。
赞赏任何意见。
谢谢,
答案 0 :(得分:2)
是的,“不使用”库函数可能仍然是错误,即使您不打算调用代码。它可以推迟一些组件的加载直到以后,所以它可能不会导致错误。最好不要引用不存在的东西(或手动加载库并获取地址,如果函数不存在,你会从“查找函数”调用中得到错误,你可以做一些事情在代码中明智)。
加载器(加载二进制可执行文件的代码)不是很聪明,所以它无法准确知道被调用的是什么,什么不是。也有可能不同的编译器对“死代码删除”具有不同的聪明程度,因此一个编译器完全删除了“从未调用”函数,但是另一个编译器不会删除它[因为它没有得到100%认证的聪明才智你永远不会调用函数 - 例如,在gcc中,如果你使libimgclientFNXXX
成为一个静态函数,它会知道这一点 - 因为它知道静态函数不会在这个模块之外被调用,而且这个模块不是使用它。
答案 1 :(得分:2)
AIX要求所有符号在加载时解析,因此即使它构建正常,因为引用了符号,应用程序也不会运行。
您需要使用lazy linking作为.so(-blazy
链接选项),这会导致只在首次使用时链接缺失的函数。
你真的不应该在库中留下未定义的符号 - 如果它需要来自另一个库的符号,你应该链接到它们(除非它是一个插件,其中符号在应用程序本身中公开)。