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

ARM_Linux中GCC编译器的使用 什么是GCC:gcc的全称是GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器(GNU C Compiler),现在除了c语言,还支持C++、java、Pascal等语言。gcc支持多种硬件平台。gcc是一个可移植的编译器,支持多种硬件平台。例如ARM、X86等等。gcc不仅是个本地编译器,它还能跨平台交叉编译。所谓的本地编译器,是指编译出来的程序只能够在本地环境进行运行。而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:
多个动态链接库中,定义了同名函数,那么链接之后会使用拿个?
答:先找到哪个用哪个

Linux下GCC入门 交叉编译指在一个平台上编译生成可以在另一个平台上运行的程序。GCC 可以进行交叉编译,尤其在嵌入式开发中非常常用。在编译大型项目时,可以使用 -j 选项来加速编译过程。该选项指定并行编译时使用的线程数。 阅读详情

相关推荐

动态链接和静态链接

什么是库库从本质上来说是一种可执行的二进制文件,可以被加载到内存中运行,而根据链接时期的不同,库又可以分为静态库和动态库。链接链接就是将不同部分的代码和数据收集和组合成一个单一文件的过程,也就是把不同目标文件合并成最终可执行文件的过程,注意:这个过程不涉及内存,链接按时期的不同可以分为三种形式,分别是: 1. 编译时链接:这个其实就是我们常说的静态链接过程; 2. 装载时链接; 3. 运

leap的博客 1495

如何处理Linux动态库同名函数

记录一次采坑–如何处理Linux动态库同名函数? 技巧:多共享动态库中同名对象重复析构问题的解决方法

嵌入式技术 843

cygwin gcc 动态链接库问题

目录结构libtest/src/main.c libtest/lib/hello.c libtest/include/hello.h编译动态库cd lib gcc -I../include -fPIC -shared -o libhello.dll hello.c解决办法我本来生成的是libhello.lib,在linux系统上完全可以,但cygwin上就是不行,一直以为是gcc 的问题,搞了半

程序猿进化史 1955

多个c/c++动态库函数同名冲突解决方法

最近某个程序需要调用多个动态库,但是不同的动态库中使用了功能不同的同名函数,导致调用出现偏差,可参考以下解决办法。 样例 假设有动态库libFuncA.so和libFuncB.so,他们的内部实现分别为: /*func_A.c*/ #include<stdio.h> //内部函数 int sayHi() { printf("Hi,this is AAAAA\n"); return 0; } //外部调用函数 int sayOut() { sayHi();

woniuye的博客 7706

Linux系统下有关GCC的介绍和库函数的生成使用

gcc 生成 .a静态库和 .so动态库

lxy13608322474的博客 541

深入Linux下的GCC编译器:从入门到精通

GCC最初作为GNU操作系统的官方编译器被开发,现在已经成为最流行的编译器之一。它被设计为可移植的,并且可以在多种架构上编译出高效的代码。GCC通过预处理器、编译器、汇编器和链接器四个阶段处理代码,将源代码转换成机器语言。在深入探讨静态和动态链接之前,我们首先需要了解链接的概念。链接是指在编译过程的最后阶段,编译器或链接器将各个编译单元(如目标代码、库文件等)合并为一个单一的可执行文件的过程。

小灰灰的博客 2226

Linux:解决应用程序/动态库中与加载的其他动态库的函数 重名问题

Linux:解决应用程序/动态库中与加载的其他动态库的函数 重名问题 问题 : 今天客户提出来一个大问题,Linux版本的一段程序,显示正常的pdf在识别的时候,程序崩了,这个不应该啊。就算pdf是坏的,那也应该有错误码,而不应该崩掉啊。 在复现的过程中,gdb调试发现,在我们的动态库A.so中有个接口叫F_Recg(),我们调用的底层还有个用的别人提供的动态库B.so,其中有个函数也叫F_Re...

buknow的博客 1731

FreeRTOS OTA实战:从Bootloader设计到安全升级的完整流程(附MQTT示例代码)

本文详细介绍了在FreeRTOS系统中实现安全OTA固件升级的完整流程。内容涵盖从Bootloader设计、存储分区规划到与MQTT协议集成的OTA Agent任务开发,并重点解析了固件签名验证、防回滚等关键安全机制,为嵌入式物联网设备提供了一套高可靠性的远程升级解决方案。

weixin_29248653的博客 161

linux .so 文件中函数名称和程序中的函数名称相同

~/so_test $ cat testlib.h #ifndef __LIB_TEST_H__ #define __LIB_TEST_H__ void libxx(); #endif ~/so_test $ cat testlib.c #include #include void libxx() { printf("come from libxx.so\n"); } ~/so_t

tsh185的专栏 2586

CST毫米波雷达ADAS仿真:从直角反射器到距离多普勒(RD图)的实战解析

本文通过CST Studio Suite实战解析毫米波汽车雷达ADAS仿真,详细演示了从构建直角反射器目标、参数化定义速度、进行参数扫描到生成距离多普勒图(RD图)的全过程。文章深入探讨了雷达关键参数(如距离分辨率、速度分辨率)的设计权衡与工程逻辑,并提供了单位统一、速度范围设定等实用避坑指南,帮助工程师高效完成雷达系统性能的前期验证与优化。

weixin_29292535的博客 502

AWD线下攻防赛总结

在本地组策略编辑器里面,依次展开计算机配置—>管理模板—>Windows组件—>远程桌面服务—>远程桌面会话主机—>连接—>限制连接的数量。8.Web目录环境查找相关可疑文件:jpg/png/rar,属性、解压。进程线程:netstat / ps -aux/netstat -apt。4.查看/etc/init.d/rc.local中启动服务有无异常。1.不使用默认口令,修改成复杂的,并确保和web环境连接。5.使用脚本开启进程监控、目录监控、流量监控。文件操作监控.exe/御剑文件监控.exe。

XuJL89的博客 630

Linux动态库与静态库同名函数链接顺序问题

linux gcc编译链接动态库与静态库同名函数顺序问题

mrhjlong 1789

【YOLOv11改进- 主干网络】YOLOv11+RepViT: 从ViT的角度重新审视Mobile的CNN助力YOLOv11有效涨点;

本文给大家带来的改进内容是在YOLOv11中更换主干网络为RepViT,助力YOLOv11有效涨点,论文通过集成轻量级 ViT 的高效架构设计,逐步增强了标准轻量级 CNN(即 MobileNetV3)的移动友好性。这最终产生了一个新的纯轻量级 CNN 系列的主干网络。

qq_41304809的博客 786

Linux下GCC编译过程及静态链接库和动态链接库

一 gcc编译过程 我们知道gcc是一个强大的编译器,很多Linux下的GNU工具都是用C语言写的,并且用gcc编译的,那么gcc的编译过程是怎样的呢,先来看一个总的流程图,我自己简单画的,凑合着看 1首先是源文件经过预加载变成了.i结尾的文件,可以通过-E这个参数来生成这个中间文件,这里主要是把一些include的头文件和一些宏定义,放到源文件中。 2从预加载的文件经过编译就会变成汇编语...

zjy900507的博客 1万+

仿真系列专栏介绍

大家好!欢迎来到我的仿真学习系列专栏!这是一个我在学习仿真技术过程中整理和分享的系列文章。作为一名正在不断学习和实践的工程师,我希望通过这个专栏,和大家一起探索仿真技术,尤其是在高速信号完整性方面的应用。

案例文章,高速信号 368

ESP32-C3入门教程 环境篇③——VS Code IDE快速入门

文章目录一、安装Visual Studio Code二、安装扩展三、配置ESP-IDF 插件四、创建工程五、配置工程5.1 选择目标芯片5.2 项目配置六、编译工程七、固件分析七、固件下载八、串口日志九、单步调试 一、安装Visual Studio Code 下载并安装Visual Studio Code 二、安装扩展 左侧扩展 搜索espressif 点击安装 三、配置ESP-IDF 插件 按下F1按键 输入configure esp-idf extension EXPRESS,如果你

8304

【Linux应用开发·入门指南】如何在Linux上安装VScode、gcc编译流程以及如何进行静态/动态链接的打包使用·详细步骤演示

本文系统介绍了Linux下C语言开发环境的搭建与使用。解析了GCC、glibc和GNUC的关系,详细演示了在Linux上安装GCC和VSCode的步骤,包括VSCode的汉化和C语言开发环境配置。重点讲解了GCC的完整编译流程(预处理→编译→汇编→链接),对比分析了静态链接和动态链接的区别与实现方法,并提供了动态库的打包和使用方案。

时光の尘的博客 2288

Bash Shell 系统巡检脚本

部分安全相关检查需要root权限,建议通过sudo运行完整检查。

老韩的Linux云计算架构师进阶之路 96

gcc/g++使用自定义的同名函数覆盖C库函数

前言 其实这问题以前就想过,每次都没有深究到底。原因在于无论是哪本Linux C编程的书,基本都会使用可靠语义的signal函数来覆盖相应的库函数。 比如在《Unix网络编程》中是如下定义的:对被SIGALRM以外的信号中断的系统调用自动重启,并且不阻塞其他的信号。(虽然信号掩码是空,但是POSIX保证被捕获的信号在其信号处理函数运行期间总是阻塞的)但是书中并未提及具体怎么覆盖库函数的定义, 毕竟...

无名小卒 1356

C#对接EtherNet/IP协议 完整版|罗克韦尔AB PLC通信+CIP核心概念全解析

你做罗克韦尔(AB) PLC工业上位机开发,是唯一的首选协议,没有之一!EtherNet/IP(Ethernet Industrial Protocol)是基于标准以太网的工业级通信协议,由罗克韦尔自动化主导开发,是ODVA(开放设备网络供应商协会)主推的工业以太网标准,也是目前全球应用最广泛的工业以太网协议之一。原生适配罗克韦尔AB PLC:Micro800、CompactLogix、ControlLogix、Micro850等全系AB PLC原生标配EtherNet/IP,无需额外配置,开箱即用;

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 892

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Linux GCC编译过程及生成静态链接库和动态链接库

一 gcc编译过程 我们知道gcc是一个强大的编译器,很多Linux下的GNU工具都是用C语言写的,并且用gcc编译的,那么gcc的编译过程是怎样的呢,先来看一个总的流程图,我自己简单画的,凑合着看 1首先是源文件经过预加载变成了.i结尾的文件,可以通过-E这个参数来生成这个中间文件,这里主要是把一些include的头文件和一些宏定义,放到源文件中。 2从预加载的文件经过编译就会变成汇编语言的文件,这一步可以通过-S这个参数来生成这个中间文件 3从汇编语言的文件通过汇编,就会变成目标代码.o的文件...

2148

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

linux下用gcc创建静态链接库和动态链接库

上一篇文章介绍了在windows下如何创建静态链接库和动态链接库(http://blog.youkuaiyun.com/love_cppandc/article/details/8502773),这一篇介绍一下在linux下如何创建静态链接库和动态链接库。 在linux下,静态库文件是.a结尾,动态库文件是.so结尾。 1.静态链接库 首先创建3个文件:static.h static.c test.c

Sun_tester的专栏 2201

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

深入探秘编译之道:在GCC的世界里雕刻代码与梦想,Linux中的GCC编译器原理与使用详解

在计算机科学的浩瀚宇宙中,编译器是承载着人类思想与机器语言之间的桥梁。而在这个领域中,GCC(GNU CompilerCollection)无疑是最具传奇色彩的存在之一。作为Linux世界中最为广泛使用的编译器,GCC不仅仅是程序员手中的工具,它更是一把通向计算机奥秘的钥匙,揭示了语言如何变为机器指令,如何将思维转换为计算的力量。GCC,这个名字曾伴随无数程序员的日日夜夜,成为编程的必备工具。今天,我们将穿越编译的迷雾,走近GCC,探索其背后的编译原理和实际使用,领略这位伟大的“编译大师”的魅力。

2303_81060385的博客 1780

Linux下GCC静态动态链接库的使用

Makefile书写规则1.语法规则2.Makefile中通配符的使用3.文件搜寻 Makefile书写规则包括两个部分,一个是依赖关系,一个是生成目标的方法。Makefile中生成的目标文件可能有很多个,但是只应该有一个最终目标,所以应该把最终目标写在第一条规则的位置。如果在第一条规则中写了多个目标,那么这些目标中的第一个会被认为是最终目标。 1.语法规则 简单的语法规则不再赘述,之前已经完成了...

Hundreays 332

Linux中GCC

介绍GCC(GNU Compiler Collection)编译器的编译过程。在写笔记过程中,参考大家的内容也学习到了很多知识,正所谓温故知新。有不妥之处请各位指点。

weixin_73788177的博客 2557

【Linux】Linux编译器 --- gcc和g++的使用

本文讲述了gcc和g++的使用、以及编译 + 链接,简单提及了动静态库

Weraphael的博客 2051
上一篇: fs_struct,file_struct,file,file_operations等的关联关系
下一篇: 原子操作,自旋锁,信号量,互斥体,顺序锁
alex_mist
博客等级 码龄9年 17粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值