首页 > 其他分享 >未定义符号的链接问题通用解决方法

未定义符号的链接问题通用解决方法

时间:2023-03-07 13:44:23浏览次数:39  
标签:set 1.0 gst 未定义 符号 usr linux audio 链接

在linux下做c/c++开发时,经常遇到一个问题,就是如果代码引用了大量的第三方库,链接的时候常忘记或者根本就不知道具体要链接哪个库,导致
链接的时候报未定义的引用,特别是一些库你不太熟悉时,甚至都不知道该链接谁。

/usr/bin/ld: CMakeFiles/gstdemo.dir/main.c.o: in function `main':
/home/a/test/gstdemo/main.c:178: undefined reference to `gst_audio_info_set_format'
/usr/bin/ld: /home/a/test/gstdemo/main.c:179: undefined reference to `gst_audio_info_to_caps'

如何解决这个问题?以往我只能靠网络上搜索,但是全得凭运气,万一搜索不到呢?其实在对应的动态库文件里面的符号表就会包含里面定义的函数或者调
用的函数。所以用grep进行搜索就找得到相关的库文件。例如对于上面未定义的引用,

grep -snr "gst_audio_info_set_format" /usr/lib/x86_64-linux-gnu/

Binary file /usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0.1603.0 matches
Binary file /usr/lib/x86_64-linux-gnu/libgstbadaudio-1.0.so.0.1603.0 matches
Binary file /usr/lib/x86_64-linux-gnu/girepository-1.0/GstAudio-1.0.typelib matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstdecklink.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvorbis.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstwavpack.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstalaw.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmpg123.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstspeex.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstinterleave.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstrawparse.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmulaw.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstopus.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstadpcmdec.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstdv.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstdtsdec.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstlibav.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmxf.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstsiren.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstsbc.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstgsm.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstfaad.so matches
Binary file /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstflac.so matches

这么多库中,一般来说只会有一个地方是真正定义函数的,其他都是调用它,这时候可以通过readelf工具查看谁定义了它,readelf的-s选项可以查看符
号表信息,

readelf -s gstreamer-1.0/libgstopus.so

Symbol table '.dynsym' contains 155 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_tag_list_new_empty
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND g_free
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_decoder_set_lat
     ....
     ....
     ....

readelf -s会输出多列内容,其中Ndx这一列如果是UND表示此elf文件(这里是动态库)没定义这个符号,是引用的一个外部符号(这里是函数),
也就是说当前这个库会调用一个其他库定义的函数,当Ndx为一个具体数字时,表示此符号是这个elf文件内部定义的,也就是说我们要链接的就是这个动态库。

grep -snr "gst_audio_info_set_format" /usr/lib/x86_64-linux-gnu/ | awk '{print $3}' | xargs readelf -s | grep "gst_audio_info_set_format"
   
   502: 000000000001b1a0   518 FUNC    GLOBAL DEFAULT   14 gst_audio_info_set_format
   137: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
    66: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   152: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   114: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    38: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    66: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   135: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   142: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   104: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    41: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    69: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    37: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   166: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    68: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   213: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   256: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    26: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    57: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    46: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
    55: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format
   229: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND gst_audio_info_set_format

可以看出来第一个grep出来的so文件定义了gst_audio_info_set_format这个函数。so文件为/usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0.1603.0
直接通过-l指定连接路径就行了,但是又可能头文件位置不知道,又得-I来指定,实在麻烦。其实在linux下可以通过pkg-config命令来获取这些信息。

pkg-config命令工作原理是搜索指定路径里面的.pc文件,而pc文件里面就描述了库的详细信息,包括头文件,库的路径,它的依赖库。例如此处,输出需要的链接信息

pkg-config --libs gstreamer-audio-1.0
-lgstaudio-1.0 -lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0

输出需要的CFLAGS信息,

pkg-config --cflags gstreamer-audio-1.0
-I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -pthread -I/usr/include/orc-0.4

通常会指定这2个选项

gcc main.c -o main `pkg-config --libs --cflags gstreamer-audio-1.0`

此处有个问题,怎么通过so文件找到对于的pc文件?我暂时至能通过看名字,两者的关联不知道怎么查看。

标签:set,1.0,gst,未定义,符号,usr,linux,audio,链接
From: https://www.cnblogs.com/thammer/p/17187860.html

相关文章

  • 项目案例丨小疆RS232转PROFINET网关链接磁栅尺MAS-200与PLC的配置
    本案例是用北京小疆智控(北京)技术有限公司生产的GW-PN5102型RS232转PROFINET网关连接磁栅尺MAS-200与PLC的配置案例,用到设备为西门子S7-1200PLC,GW-PN5102型RS232转PROFINET......
  • windows下载符号
    1"C:\ProgramFiles(x86)\WindowsKits\10\Debuggers\x86\symchk.exe""c:\windows\system32\calc.exe"/sSRV*c:\symbols\*http://msdl.microsoft.com/download/symbo......
  • 什么是无符号字符?
    在C/C++中,anunsignedchar是干什么用的?它与普通的有何不同char?解答http://www.stackoverflow.ink/posts/shi-yao-shi-wu-fu-hao-zi-fu/......
  • 如何从 .NET 中的字符串中删除变音符号(重音符号)?
    我正在尝试转换一些加拿大法语字符串,基本上,我希望能够在保留字母的同时去掉字母中的法语重音符号。(例如转换é为e,所以crèmebrûlée会变成cremebrulee)实现这一目标......
  • 批量下载浏览器网页中全部链接的方法
      本文介绍在Chrome浏览器中,通过迅雷自动批量选中网页中全部下载链接并进行下载的方法。  前期的文章批量下载Landsat遥感影像的方法中,我们详细介绍了USGS遥感影像批......
  • 《C语言中char是根据编译器来确定是有符号还是无符号》
    在C语言中,char类型的有无符号是依赖于具体的编译器实现的。在一些编译器中,char类型是有符号的,而在另一些编译器中,char类型是无符号的。由于C语言标准并没有规定char类型应......
  • thinpphp6+php8.0.2链接PGSQL12
    1、提示   如果是pgsql12以下的执行CREATEORREPLACEFUNCTIONpgsql_type(a_typevarchar)RETURNSvarcharAS$BODY$DECLAREv_typevarchar;BEGINIF......
  • Maven链接数据库(3.6)
     报错应该是Usermapper中查询语句错误 链接数据库之后的数据库语句放在mapper文件夹下的UserMapper中 右键com.baidu.pojo→new→package→命名com.baidu.util(前缀......
  • c语言中有符号和无符号数字
    https://nju-projectn.github.io/ics-pa-gitbook/ics2022/why.html#数组求和数组求和intsum(inta[],unsignedlen){inti,sum=0;for(i=0;i<=len-1;i++)......
  • 矩阵符号的不同情景展现
    在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方程组的系数及常数所构成的方阵。矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中......