即使在链接具有定义的库之后,也会出现“对函数的未定义引用"问题 [英] 'Undefined reference to function' issue even after linking the library which has the defination

查看:350
本文介绍了即使在链接具有定义的库之后,也会出现“对函数的未定义引用"问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to create an executable with .o ,.so, .a files.

这是我的构建命令:-

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"上有函数的定义.仍然在下面抛出错误.

I have libraries which have definitions of the functions at path "-L/home/dlb/extlibs/arm/lib" . Still it is throwing error below.

错误:

../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的位置:-

I have the symbol in library which is at path /home/dlb/extlibs/arm/lib :-

命令:-

readelf -s libitcl4.0.0.so | grep ptrlitclStubsPtr

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr

我在这里错过了什么吗?

Am I missing some thing here?

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

Note, OP has provided more info in a repost of the same question;
quote from comment by OP:
"Due to some privacy issues...I am renaming the symbols.. It was edited by me... It was typo...I just corrected it...:)"
I.e. the identifiers in the error message and the grep line and the output of the grep line have been manually altered.

推荐答案

您要查询的函数似乎在定义它们的文件中是 local .也就是说,看起来它们是明确地不希望(甚至不允许)从外部调用的.

It looks like the functions you're asking about are local to the file where they were defined. That is, it looks like they were explicitly intended not (and not even allowed) to be called externally.

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

That is, somewhere within the source for the shared library libitcl4.0.0.so probably appears a declaration like:

static tclStubs *ptrlitclStubsPtr;

关键字static表示结果符号ptrlitclStubsPtr visibility 限于其自己的源文件.

That keyword static indicates that the visibility of the resulting symbol ptrlitclStubsPtr is confined to its own source file.

我从您报告的readelf输出包含该行的事实推断出了所有这些情况

I infer all of this from the fact that your reported readelf output includes the line

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr

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

That flag LOCAL indicates that the symbol is local. If it were global, intended (and able) to be called externally, the flag GLOBAL would appear instead.

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

Why are variables made private (static) like this, so you can't use them? It's a software engineering thing, "information hiding", intended to reduce the "width" of the interface between you and a library like libitcl4. Symbols that are private are more intimately tied to the implementation decisions within libitcl4, decisions which are not supposed to be visible to, or any concern of, the callers. It's thought that, if callers were to have access to those symbols, callers would also have to know other implementation details, meaning that the author of libitcl4 would then be unable to change those implementation details without breaking (invalidating) the calling code. So to prevent that situation, the choice is usually made to make it impossible for the caller to become dependent in this way.

在这种情况下,您基本上有3条前进的路径:

In this situation you basically have three paths forward:

  1. static标记从源变量声明中删除到libitcl4.0.0.so. (这显然要求您有权访问libitcl4.0.0.so的源代码,并具有重建它的能力.这可能也是一个非常糟糕的主意.正如我所解释的,这些符号很可能是静态的,这是有充分原因的.)

  1. Remove the static tags from the variable declarations in the sources to libitcl4.0.0.so. (This obviously requires that you have access to the sources to libitcl4.0.0.so, and the ability to rebuild it. It's also probably a very bad idea. As I've explained, those symbols were probably made static for a good reason.)

libitcl4.0.0.so中添加一个新功能,该功能可以完成您需要做的所有事情,并且由于其在同一源文件中的位置,因此可以访问这些符号. (这也要求您有权访问并具有重建"libitcl4.0.0.so"的能力.)

Add a new function within libitcl4.0.0.so which does whatever you need done, and which, by virtue of its placement within the same source file, does have access to those symbols. (This, too, requires that you have access to and the ability to rebuild ``libitcl4.0.0.so`.)

使用libitcl4.0.0.so的现有公共设施找到其他方法来完成您需要做的事情.

Find some other way of doing whatever you need done, using the existing public facilities of libitcl4.0.0.so.

这篇关于即使在链接具有定义的库之后,也会出现“对函数的未定义引用"问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆