关于linux gcc的动态链接和函数同名情况

Gcc的几个参数

  1. -I(大写i,include):指定include头文件的位置
  2. -l (小写l,link):指定link库文件的名字,如库文件libhello.so,那么加入参数-lhello
  3. -L:指定找库文件的位置

例子:

gcc test7.c -o test7 -I /usr/src/linux-source-4.15.0/linux-source-4.15.0/tools/include
去/usr/src/linux-source-4.15.0/linux-source-4.15.0/tools/include找头文件

一个困扰我的问题是,我们在.c文件中include了一个头文件,头文件中有对某个函数的声明,那么gcc是如何找到对应函数的定义,然后链接生成可执行文件的呢??

于是写了个动态链接的例子:
定义头文件hello.h:

#ifndef HELLO_H_
#define HELLO_H_
#include <stdio.h>
int show(void);

#endif

定义函数定义文件hello.c:

#include <stdio.h>

void show(void)
{
	printf("hello");
	return 0;
}

定义main入口main.c:

#include "hello.h"

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

生成.so文件:

gcc -shared -fpic hello.c -o libhello.so

生成可执行文件:

gcc main.c -o main -L /home/txz/Documents/module_learn/test6 -lhello

因此,在编译生成可执行文件的时候就指定了动态链接库的位置,所以这样在运行的时候就知道去哪找了;

同名问题

情况1:
在main主程序中定义了和动态链接库同名的函数:

#include "hello.h"
//动态链接了另一个show
int show(void)
{
        printf("asd");
        return 0;
}
int main()
{

        show();
        return 0;
}

编译:

gcc main.c -o main -L ./ -lhello

是可以通过的,无报错,无警告,并且结果打印的在主函数中定义的内容

情况2
在main函数中定义了和C标准库函数同名的函数:

// main.c
#include <stdio.h>
int printf(void) {
    return 0;
}
int main() {
    printf("hello\n");
    return 0;
}

编译报错:

main.c:3:5: error: conflicting types for ‘printf’
 int printf(void) {
     ^~~~~~
In file included from main.c:2:0:
/usr/include/stdio.h:318:12: note: previous declaration of ‘printf’ was here
 extern int printf (const char *__restrict __format, ...);
            ^~~~~~
main.c: In function ‘main’:
main.c:7:5: error: too many arguments to function ‘printf’
     printf("hello\n");
     ^~~~~~
main.c:3:5: note: declared here
 int printf(void) {
     ^~~~~~

出现conflict,因为C库函数是built-in内建函数,和寻常自定义的函数不一样;使用和C库函数同名的函数必会conflict;

情况3:
多个动态链接库中,定义了同名函数,那么链接之后会使用拿个?
答:先找到哪个用哪个

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值