2

作为我们从 HP 到 AIX 的应用程序迁移的一部分,我面临着一个独特的问题。以下模拟代码在 HP 和 AIX 中产生不同的结果。

图书馆.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(),也存在未解决的错误。

惠普内置的完全相同的代码可以正常工作,没有错误。

任何输入表示赞赏。

谢谢,

4

2 回答 2

2

是的,“不使用”库函数可能仍然是一个错误,即使您不打算调用代码。它可能会将某些组件的加载推迟到以后,因此它可能不会导致错误。最好不要引用不存在的东西(或者手动加载库并获取地址,如果函数不存在,你会从“查找函数”调用中得到一个错误,你可以做点什么在代码中是明智的)。

加载器(加载二进制可执行文件的代码)不是很聪明,所以它不能确切地知道什么被调用,什么不是。也有可能不同的编译器对“删除死代码”有不同程度的聪明,所以一个编译器完全删除了“从未调用”的函数,但另一个编译器没有删除它[因为它没有 100% 证明的聪明你永远不会调用这个函数——例如,在 gcc 中,如果你创建了libimgclientFNXXX一个静态函数,它会知道这一点——因为它知道静态函数不会在这个模块之外被调用,并且这个模块没有使用它。

于 2012-12-24T16:46:34.353 回答
2

AIX 要求在加载时解析所有符号,因此即使构建正常,因为引用了符号,应用程序也不会运行。

您需要对.so (链接选项)使用延迟链接-blazy,这应该会导致丢失的函数仅在首次使用时链接。

但是,您确实不应该在库中留下未定义的符号 - 如果它需要来自另一个库的符号,您应该链接到它们(除非它是一个插件,符号在应用程序本身中公开)。

于 2012-12-24T16:48:56.267 回答