首页 > 其他分享 >链接找不到符号的两种表现

链接找不到符号的两种表现

时间:2023-02-24 22:22:37浏览次数:31  
标签:两种 符号 int haha cpp main 链接

链接找不到符号的两种表现

本文分析链接时找不到符号时的两个不同表现,帮助快速定位问题。

结论

如果链接时出现找不到符号的问题,需要注意提示信息中的符号是否有函数签名信息。如果有函数签名信息,则是依赖一个C++符号,否则就是依赖一个C符号。

场景还原

库代码:

// file: haha.c
int haha()
{
    return 0;
}

生成动态库:

$ gcc -c haha.c
$ gcc -fPIC -shared haha.o -o libhaha.so 

客户代码:

// file: main.cpp
int haha();

int main()
{
    haha();
    
    return 0;
}

编译并链接动态库:

$ g++ -c main.cpp
$ g++ main.o -L. -lhaha 
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x9): undefined reference to `haha()'
collect2: error: ld returned 1 exit status

问题分析和解决

问题出在库中的符号为C符号,而引用的符号为C++符号,两者并不匹配。

符号如下:

$ nm libhaha.so | grep haha
00000000000010f9 T haha

$ nm main.o | grep haha
                 U _Z4hahav

解决办法就是将引用的符号调整为C符号,如下:

// file: main.cpp
extern "C"
{
int haha();
}

int main()
{
    haha();

    return 0;
}

重新编译后,符号一致,如下:

$ nm main.o | grep haha
                 U haha

链接器两个不同的表现

注意到,编译链接的时候的报错中的这一行:

main.cpp:(.text+0x9): undefined reference to `haha()'

报错直接给出了引用的函数签名(无参函数),这提示我们,链接的信息包含函数签名,这是C++符号的特征。

再做一个试验,观察在C中找不到一个符号的报错:

// file: main.c
int haha();

int main()
{
    haha();
    
    return 0;
}

// file: main.cpp
extern "C"
{
int haha();
}

int main()
{
    haha();

    return 0;
}

直接编译:

$ gcc -c main.c
$ gcc main.o
/usr/bin/ld: main.o: in function `main':
main.c:(.text+0xe): undefined reference to `haha'
collect2: error: ld returned 1 exit status

$ g++ -c main.cpp
$ g++ main.o
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x9): undefined reference to `haha'
collect2: error: ld returned 1 exit status

此时在提示的信息中没有函数签名,这提示我们找不到的符号是一个C符号。

标签:两种,符号,int,haha,cpp,main,链接
From: https://www.cnblogs.com/amazzzzzing/p/17153382.html

相关文章