首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 动态库 导出符号

Linux 动态库导出符号基础概念

在Linux系统中,动态库(Dynamic Link Library)是一种可被多个程序共享的库文件,通常以.so(Shared Object)为扩展名。动态库中的函数和变量可以通过“导出符号”的方式供其他程序调用。

导出符号指的是将库中的函数、变量等标识符暴露给外部程序使用。这些符号在编译时被标记为外部可见,从而允许链接器在链接阶段解析它们的地址。

相关优势

  1. 节省内存:多个程序可以共享同一个动态库实例,减少内存占用。
  2. 便于更新和维护:只需替换动态库文件,无需重新编译所有依赖它的程序。
  3. 提高灵活性:可以在运行时动态加载和卸载库,实现功能的灵活扩展。

类型

  • 全局符号:可以被所有其他模块访问的符号。
  • 局部符号:仅限于定义它们的模块内部访问的符号。

应用场景

  • 大型软件系统:将功能模块化,通过动态库实现各模块间的解耦。
  • 插件架构:允许第三方开发者编写扩展功能,通过动态库加载到主程序中。
  • 跨平台兼容性:编写一套代码,通过不同的动态库适配不同操作系统或硬件平台。

导出符号的方法

使用extern "C"

在C++中,为了防止名称修饰(Name Mangling),可以使用extern "C"声明导出的函数和变量。

代码语言:txt
复制
// mylib.h
#ifdef __cplusplus
extern "C" {
#endif

void myFunction();
int myVariable;

#ifdef __cplusplus
}
#endif

使用GCC的__attribute__((visibility("default")))

GCC提供了属性来控制符号的可见性,默认情况下,GCC会隐藏所有非全局符号。

代码语言:txt
复制
// mylib.c
#include "mylib.h"

__attribute__((visibility("default"))) void myFunction() {
    // ...
}

__attribute__((visibility("default"))) int myVariable = 42;

使用Makefile或CMake设置编译选项

在构建系统中,可以通过设置编译选项来控制符号的导出。

代码语言:txt
复制
# Makefile
CFLAGS += -fPIC -shared -Wl,-soname,libmylib.so

遇到的问题及解决方法

问题:符号未正确导出

原因:可能是由于编译器默认隐藏了符号,或者使用了错误的编译选项。

解决方法:确保使用了正确的编译选项(如-fPIC-shared),并在需要的地方添加extern "C"__attribute__((visibility("default")))

问题:符号冲突

原因:多个库中定义了相同名称的符号,导致链接时发生冲突。

解决方法:重命名冲突的符号,或者使用命名空间来避免冲突。

示例代码

假设我们有一个简单的动态库libmylib.so,其中包含一个函数myFunction和一个变量myVariable

代码语言:txt
复制
// mylib.h
#ifdef __cplusplus
extern "C" {
#endif

void myFunction();
int myVariable;

#ifdef __cplusplus
}
#endif
代码语言:txt
复制
// mylib.c
#include "mylib.h"
#include <stdio.h>

void myFunction() {
    printf("Hello from myFunction!\n");
}

int myVariable = 42;

编译动态库:

代码语言:txt
复制
gcc -fPIC -shared -o libmylib.so mylib.c

使用动态库的程序:

代码语言:txt
复制
// main.c
#include "mylib.h"

int main() {
    myFunction();
    printf("myVariable = %d\n", myVariable);
    return 0;
}

编译并运行程序:

代码语言:txt
复制
gcc -o main main.c -L. -lmylib
LD_LIBRARY_PATH=. ./main

通过以上步骤,可以看到动态库中的符号被成功导出并使用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

解决动态库的符号冲突

TIPS:可以简单的使用linux的命令 nm 查看程序里有哪些函数 动态库和符号表 尽管程序各不相同,但总有些功能很常见。...每个程序都为他们写一遍代码很不划算,于是独立出来成了库,在多个程序之间共享。一个库也可以使用别的库。有两种共享的办法:静态的,动态的。 在编译时,把库的代码复制一份合并到可执行文件里的,是静态库。...在运行时,把库的代码加载一份到内存里的,是动态库。 动态库更节省资源,不用被复制很多次,更新也方便。 负责链接的东西,叫做链接器(linker),负责加载的叫做加载器(loader)。...动态库加载之前,谁都不知道它会被加载到哪里,也就不知道动态库里的指令的地址,只能通过符号(名称)来记录它提供给别人用的函数列表(导出表),以及它期望别人提供给他的函数列表(导入表)。...库被加载后,就获得了地址。程序运行前,需要先解析符号表,确定每个符号的实际地址。

2.3K30

linux 动态库加载_linux默认动态库加载路径

当我们在linux系统引用动态库时,经常会遇到一个问题,加入我们需要的动态库没有在系统的默认目录下,我们编译时使用-L指定了动态库的路径,编译时没有问题,但是执行调用该动态库的可执行文件时,却提示找不到动态库...,使用ldd命令查看一下: 为什么我们编译的时候明明指定了动态库的路径,而且程序编译的时候没有问题,执行的时候却找不到了呢?...1、因为我们在编译的时候使用-L指定动态库的路径,只是告诉编译器我们所需要的动态库在某个目录下,只对编译起作用 2、当程序执行时,程序还是回去系统的默认路径下寻找程序运行所需的动态库 所以在程序运行的时候会出现找不到动态库的问题...解决办法,使用-Wl,-rpath 所需动态库的路径 告诉程序如果在默认路径下找不到所需动态库,则去当前指定的路径下找动态库。...修改gcc编译指令后,结果如下: 可见,动态库加载成功,程序运行成功,问题解决。 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。

11.8K20
  • Linux 编译动态库_makefile编译动态库

    动态链接库简介 动态库又叫动态链接库,是程序运行的时候加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。...动态库是目标文件的集合,目标文件在动态库中的组织方式是按特殊的方式组织形成的。在动态库中函数和变量的地址是相对地址而不是绝对地址,其真实地址在调用动态库的程序加载时形成的。...系统中的配置文件/etc/ld.so.conf便是动态链接库的搜索路径配置文件。在这个文件内存放着可以被Linux共享的动态链接库所在目录的名字(系统默认的/lib, /usr/lib除外)。.../usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/mesa-egl /usr/lib/x86_64-linux-gnu/mesa # Legacy...运行时的动态链接库需要放到系统搜索路径下。 6. 动态加载库的使用 动态加载库和动态链接库不同的是, 一般的动态链接库需要在程序启动的时候就要寻找动态链接库,找到库函数。

    6.2K20

    【Linux】静态库和动态库

    如果我们将头文件和库文件都安装到系统中了,-I 和 -L 就不需要带了。 二、动态库 1. 动态库概念 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 2....首先我们要知道,在 Linux 下,形成的可执行程序是 ELF 格式的可执行程序,它其中包含有一张类似于符号表的东西,里面包含各种函数依赖的库以及地址,符号表就是动态链接这些动态库的。...理解动态库加载 接下来我们回到地址空间中理解动态库的加载,首先磁盘中有我们的 ELF 可执行程序,可执行程序中的符号表中依赖了 libmylib.so 这样的动态库,如下图: 但是当我们将可执行程序加载到内存中后...,也要把该库加载到内存里,然后经过页表映射到进程地址空间中,一旦库加载之后,它在地址空间中的位置就是确定了,我们假设该库加载到地址空间后的地址为 0x1111,那么我们就可以将库中的符号用 0x1111...更重要的是,ELF 可执行程序会在特定的位置,记录下来自己程序的入口地址 entry;也就是,编译器在编译的时候,可执行程序在符号表中有专门的字段记录 main 函数的地址,供操作系统读取!

    74710

    linux动态库和静态库

    http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520101023104745738/ Linux下静态库_库的基本概念;如何生成静态库动态库...,加载时搜索的过程;动态库找不到的问题;库的依赖问题;动态库升级问题与步骤 一、基本概念 1.1、什么是库 在 windows 平台和 linux 平台下都大量存在着库。       ...1.2、 库的种类  linux 下的库有两种:静态库和共享库(动态库)。...在Linux下,动态库和静态库同事存在时,gcc/g++的链接程序,默认链接的动态库。...linux系统的动态库有两种使用方法:运行时动态链接库,动态加载库并在程序控制之下使用。 1、为什么在不停程序的情况下,直接用 cp 命令替换程序使用的 so 文件,会使程序崩溃?

    12.4K20

    【Linux】静态库和动态库

    Linux为什么不允许普通用户给目录建立硬链接呢? 系统层面上有.和…硬链接指向目录。...一、动态库和静态库 具体的动态库和静态库的相关内容点击跳转 Linux的库一般分为动态库和静态库: 静态库(.a):库文件以.a为后缀,程序在编译链接的时候把库的代码链接到可执行文件中。...程序运行的时候将不再需要静态库 动态库(.so):库文件以.so为后缀,程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。...究竟是动静态库,取决你提供的是动态库还是静态库。...: 静态库采用的是绝对编址 动态库采用的是相对编址,动态库中的指定函数的地址通过相对编址(库中的偏移地址+段起始地址): 动态库打包:-shared gcc -shared -o libmymath.so

    32230

    Linux共享库控制导出函数

    之前的文章介绍了Linux中对共享库中同名函数的处理规则——根据链接库的顺序来确定调用哪个函数。 本次介绍共享库其他一些有意思的性质。...使用链接库的顺序来处理,显然不是一个好办法。...【虽然大部分情况下库的函数名称都是不一样的】 再来一个场景,当我们拿到第三方库和头文件,我们还想看下库里面还有哪些其他的函数接口,这时可以使用 nm -D *.so 进行查看。.... # 内部头文件 INC_CFLAGS += -I $(APP_STACK_DIR)/Inc # 对外接口目录 #INC_CFLAGS += -I $(APP_STACK_DIR)/Intf # 动态链接库...-lName # 源文件 CSRC += $(APP_STACK_DIR)/Src/*.c C_OBJS += $(patsubst %.c,%.o,$(wildcard $(CSRC))) # 动态库编译标志

    2.4K20

    Linux共享库、静态库、动态库详解

    1、静态函数库,是在程序执行前就加入到目标程序中去了 ; 2、动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll)...通常,动态函数库的符号表里面包含了这些动态的对象的符号。这个选项在创建ELF格式的文件时候,会将所有的符号加入到动态符号表中。可以参考ld的帮助获得更详细的说明。 3.5....通常,动态符号表仅包含动态对象使用的符号。此选项(创建ELF文件时)将所有符号添加到动态符号表(有关详细信息,请参阅ld(1))。...当有“反向相关性”时,您需要使用此选项,即,DL库具有未解决的符号,按照惯例,必须在要加载这些库的程序中定义它们。对于“反向相关性”工作,主程序必须使其符号动态可用。...导出的功能被删除。 导出功能的界面发生变化。 如果可以避免这些原因,可以使您的库二进制兼容。换句话说,如果您避免此类更改,您可以保持您的应用程序二进制接口(ABI)兼容。

    8.9K11

    linux 动态库 静态库_静态库里面包含动态库

    动态库与静态库 文件系统补完 文件的三个时间acm 动态库与静态库 动态链接与静态链接 静态库与动态库 动静态库的对比 生成静态库 打包静态库 使用静态库 生成动态库 打包动态库 使用动态库 文件系统补完...可以使用:1.库,包括静态库与动态库。2.开源代码。3.基本的网络功能调用,比如各种网络接口、语音识别等等。 这其中,我们将详细介绍静态库和动态库。...动态库是动态链接生成的,而静态库是静态链接生成的。...程序运行的时候将不再需要静态库。 而动态库则是指程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。...生成动态库 学习完生成和使用静态库后,下面我们来生成一下动态库。

    7.4K20

    Linux静态库与动态库加载

    2.编译: 完成词法分析、语法分析、语义分析、符号汇总等,检查无误后将代码翻译成汇编指令,最终形成XXX.s文件。 3.汇编: 将汇编指令转换成二进制指令,最终形成xxx.o文件。...,简单来说就是动态库。...在Linux当中,以.so为后缀的是动态库,以.a为后缀的是静态库。 在Windows当中,以.dll为后缀的是动态库,以.lib为后缀的是静态库。 认识了动态库,那静态库,又是什么呢?...,不再需要库,但动态库不行,在日常我们都会使用动态库,很少使用静态库。...注意上面我打包了两个库,虽然看后缀一个静态库,一个动态库,但是其实上述的库都是静态库,linux不是单单通过后缀来判断一个库的类型,下面就来看看如何真正打包一个动态库吧。

    18510

    Linux之动态库和静态库

    前言 一、动态库和静态库概念 在之前的文章中,介绍过动静态库的概念,因此这次我们只是简单回顾一下。 Linux中的库分为动态库和静态库。...动态库(.so):库文件以.so为后缀,程序在运行时才去链接动态库的代码(运行时跳转到动态库中,在动态库中执行库函数)。多个程序共享库的代码。 链接的本质:我们调用库函数时是如何与标准库联系的。...动态库相对于静态库更节省内存,静态库由多个程序使用相同的库函数,加载到内存中就会导致内存中有多份重复的库函数代码,而动态库则是多个程序共用一份动态库,不会导致出现重复的库函数代码,就节省了内存空间。...总结 以上就是今天要讲的内容,本文介绍了Linux中的动静态库的相关概念。...本文作者目前也是正在学习Linux相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。

    59520

    DLL 导出符号的两种方式

    最近恰好需要用 C++ 实现一个供 C# .NET 调用的模块,用dllexport导出符号的时候出现了一点问题,明明已经看到了导出符号,但是 .NET 在调用的时候,就是找不到方法。...然后用 def 文件的方式导出符号就正常,突然对这两种方式的区别产生兴趣,之前一直没有研究过,就仔细了查阅一番。...区别 这里就不得不说导出符号在 DLL 中的形式。...实际上对于 C++ 来说,当导出的时候,不会以原名导出,因为会加上一些符号字母后缀,实际上如果了解 C++ 的人,也会知道 C++ 在处理函数重载的时候,其实也用了这个套路,实际上编译之后就没有重载的概念了...所以会看到有时候导出的时候_extern "C" _declspec(dllexport)这样写,这是为了让函数以 C 的方式来编译,这样导出的方法就是没有那些符号的了,但这样有个问题,就是函数必须以

    1.5K40

    linux编译curl库的动态库so

    转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)  curl库是一个很强大的http开源库,c++里面能够很方便的和http服务器交互。...最近项目开始内测,开始接登录和充值的SDK,选择了使用curl库来和第三方http服务器交互。...在windows下还是很容易使用,如何使用的案例比比皆是,而且很容易就找到已经编译好的动态库进行测试,但是最后在linux下部署的时候,发现不好找已经编译好的so库文件,最后没办法只好自理更生。...我是使用腾讯的SDK里面附带的curl库的源码(ps,腾讯SDK的示例代码貌似没在linux测试过,我编译后使用他们的代码,发现很容易崩溃,需要修改才能运行,但是windows正常)。...包含了编译生产的库、头文件等。 然后为了能够方便的移植我们的程序,把include/lib下面的头文件和so库文件拷贝到自己的工程目录就能使用curl库了。

    6.5K10

    Linux下的静态库与动态库

    由于windows和linux的本质不同,因此二者库的二进制是不兼容的。本文仅限于介绍linux下的库。 2.库的种类 linux下的库有两种:静态库和共享库(动态库)。...4.库文件是如何产生的在linux下 静态库的后缀是.a,它的产生分两步 Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表 Step 2.ar命令将很多.o转换成.a,成文静态库...动态库的后缀是.so,它由gcc加特定参数编译产生。...在linux下,库文件一般放在/usr/lib /lib下, 静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称 动态库的名字一般为libxxxx.so.major.minor,xxxx...库和ld-linux库 7.可执行程序在执行的时候如何定位共享库文件 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径 此时就需要系统动态载入器(dynamic linker

    9610

    Linux动态库管理详解:增加动态库目录和实用技巧

    引言 在Linux操作系统中,动态库是一种特殊的二进制文件,它包含了在多个应用程序中可共享的代码和数据。然而,对于开发者和系统管理员来说,管理这些动态库可能并不是一件简单的事。...本文将深入探讨Linux动态库的管理,包括如何增加动态库目录,以及一些与动态库相关的实用技巧。 动态库简介 在深入讨论之前,让我们先了解一下什么是动态库。...允许多个程序共享同一份库代码。 增加动态库目录 Linux系统通常在/lib,/usr/lib或/usr/local/lib等几个标准目录中查找动态库。但有时,我们可能需要在其他目录中存放动态库。...ldd /path/to/your/application 创建符号链接 当动态库版本更新后,可以创建一个符号链接,而不是重新编译应用程序。...增加动态库目录和了解一些实用技巧,不仅可以让你更灵活地管理系统,还能解决一些常见的依赖问题。希望本文能帮助你更深入地理解Linux动态库的管理。

    1.9K41

    【Linux】动态库与静态库的底层比较

    2 编译使用比较 那么 gcc编译的时候是怎么进行的: gcc不加-static选项默认使用动态库,没有提供动态库就只能使用静态库 gcc加-static选项就使用静态库 那么-static的意义是什么呢...但是对应的方法并没有在可执行程序中,所以动态库是怎样被调用的呢?又是什么时候被调用呢? 动态库也会写入到内存中,并通过页表映射到地址空间中的共享区。让调用的时候通过共享区来找到对应的方法实现。...其他的可执行文件相要调用动态库中的方法是,也可以通过页表来映射就可以。所以动态库只需要在内存中存在一份 有个问题:我们的可执行程序,编译成功之后,如果没有加载运行,二进制代码中有没有对应的“地址”?...: 先来看看动态库的回报代码,发现也是使用平坦模式进行编址的!...所以同样的,与加载可执行程序类似,会把动态库读入内存中,并建立对应的页表映射,**动态库的虚拟地址在进程地址空间里是在共享区里的。

    23410
    领券