c++程序链接阶段:undefined reference to xxx function(未定义引用问题)原因解析

问题分析

c++程序,在链接阶段,当你的程序引用了第三方库中定义的函数时(程序内部定义的函数不涉及这个问题,因为函数的实现已经在自己的代码段、数据段中了),连接器会在三方库中搜索当前符号表中未定义的符号(这些未定义的符号需要在三方库中定位到,否则就会出现对xxx函数未定义引用),当在三方库的符号表中找不到对应的符号时,就会报undefined reference to xxx function。

注意,当遇到这个问题时,首先要排除是否三方库有没有被正确链接。当三方库没有被正确链接时,报的错误通常是“can not find -lxxxlib”,即找不到xxx库,而不是未定义引用,所以,遇到未定义问题时,说明库已经链接上了,但是没找到符号。

有两个导致未定义引用的原因:

  1. 三方库确实没有该符号,或者没有该符号的定义。通过readelf -s xxx.lib可以查看三方库中该符号的状态,如果该符号缺失,或者该符号是未定义的,那么说明三方库本身有问题。
  2. 三方库中确实定义了该符号,但是你的连接器没找到。为什么会没找到呢?最可能的原因,是你混合c/c++编程时,会遇到的:即三方库是c库,提供的符号都是按c编译器生成的,没有经过命名混淆的(name mangling),比如对于三方库中某个函数int add(double, double),按c编译器编译出来后形成的符号是类似_add这种,但是按照c++编译器生成的符号是诸如_adddd这种,那么,当你的c++程序中,包含了第三方c库的头文件时,c++编译器会给三方库中的函数名字也name mangling一下,然后尝试在三方库中搜索类似_adddd这样的符号,显然,这样的符号是不在三方库中的。

解决办法

解决办法很简答,即用extern C { your function decleration }把你的函数生命包住,此时括号内的函数会用c编译器方式去编译,生成的的符号不会有name mangling,该符号在三方库xxx.lib中存在,此时也就消除了未定义引用的问题。

extern c可以用来包裹#include your_header,也可以包裹单个或多个函数生命,看你自己的需求
c++程序链接阶段:undefined reference to xxx function(未定义引用问题)原因解析
c++程序链接阶段:undefined reference to xxx function(未定义引用问题)原因解析

参考链接

  1. “undefined reference to” errors when linking static C library with C++ code
  2. Mixing C and C++… undefined reference to function [closed]
  3. 为什么需要 extern “C” ?