我正在尝试使用.o,.so,.a文件创建可执行文件。

这是我的构建命令:

pkgs/gcc/v4.8.3/bin/gcc -L/usr/X11R6/lib -O2 -DUSE_FLEX -Wall -Wno-char-subscripts -fPIC -DLINUX -DG_DISABLE_CONST_RETURNS -fno-strict-aliasing -o ../build/kl/Release/test/bin/pure.exe -L../build/kl/Release/test/modules ../build/kl/Release/test/maker/constrfunc.TCL.o ../../build/kl/Release/test/maker/pvdbprocs.TCL.o .. ../build/kl/Release/test/maker/maker/memmaker.TCL.o .. ../build/kl/Release/test/maker/modules/libdenbase.a .. ../build/kl/Release/test/maker/guibase.o -litk3.2 -litcl4.0.0 -ltk8.3 -lcdnviptcl8.4 -litclstub4.0.0 -ldenbase -lglib-2.0 -ldenbase -lX11 -ldl -lm -lviputil -lvippli -lcdsCommonMT_sh -lpthread  -L/home/dlb/extlibs/arm/lib


我有一些库,这些库在路径“ -L / home / dlb / extlibs / arm / lib”处具有函数的定义。仍然在下面抛出错误。

错误:

../build/kl/Release/test/maker/guibase.o: In function `decodeAddrList':
tree234.c:(.text+0xc): undefined reference to `ptritclStubsPtr'
tree234.c:(.text+0x20): undefined reference to `ptrlitclStubsPtr'
tree234.c:(.text+0x12c): undefined reference to `ptrlitclStubsPtr'
tree234.c:(.text+0x140): undefined reference to `ptrlitclStubsPtr'


我在路径/ home / dlb / extlibs / arm / lib中的库中有符号:

命令:-

readelf -s libitcl4.0.0.so | grep ptrlitclStubsPtr

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr


我在这里想念什么吗?

注意,OP在相同问题的转发中提供了更多信息;
OP的评论语录:
“由于一些隐私问题,我正在重命名符号。它是由我编辑的。这是错字。我刚刚更正了它。。。)”
即错误消息中的标识符和grep行以及grep行的输出已被手动更改。

最佳答案

您要查询的功能似乎在定义它们的文件中是本地的。也就是说,它们似乎是明确地不希望(甚至不允许)从外部调用的。

也就是说,共享库libitcl4.0.0.so的源代码中某处可能会出现一个声明,例如:

static tclStubs *ptrlitclStubsPtr;


关键字static表示结果符号ptrlitclStubsPtr的可见性仅限于其自己的源文件。

我从您报告的readelf输出包含以下行这一事实推断出了所有这些信息:

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr


该标志LOCAL表示该符号是本地符号。如果它是全局的,并且打算(并且能够)从外部调用,则将改为显示标志GLOBAL

为什么将这样的变量设为私有(static),所以不能使用它们?这是软件工程,“信息隐藏”,旨在减少您与libitcl4之类的库之间的接口“宽度”。私有符号与libitcl4中的实现决策紧密相关,这些决策对于调用者而言不可见,也不对其涉及。人们认为,如果调用者可以访问这些符号,则调用者还必须知道其他实现细节,这意味着libitcl4的作者将无法在不破坏(使调用代码无效)调用代码的情况下更改这些实现细节。因此,为避免这种情况,通常会做出选择,以使呼叫者无法以这种方式变得依赖。

在这种情况下,您基本上有以下三种方法:


static源代码中的变量声明中删除libitcl4.0.0.so标记。 (这显然要求您有权访问libitcl4.0.0.so的资源,并具有重建它的能力。这可能也是一个非常糟糕的主意。正如我所解释的那样,这些符号很可能是静态设置的。)
libitcl4.0.0.so中添加一个新功能,该功能可以完成您需要做的所有事情,并且由于其在同一源文件中的位置,因此可以访问这些符号。 (这也要求您有权访问并能够重建``libitcl4.0.0.so`。)
使用libitcl4.0.0.so的现有公共设施,找到其他方法来完成您需要做的事情。

关于c - 即使在链接具有定义的库之后,也会出现“对函数的 undefined reference ”问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50445789/

10-10 07:24