Linux下gcc编译生成动态链接库*.so文件并调用它

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。
1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

//so_test.h:
#include "stdio.h"
void test_a();
void test_b();
void test_c();

//test_a.c:
#include "so_test.h"
void test_a()
{
  printf("this is in test_a...\n");
}


//test_b.c:
#include "so_test.h"
void test_b()
{
  printf("this is in test_b...\n");
}



//test_c.c:
#include "so_test.h"
void test_c()
{
  printf("this is in test_c...\n");
}
将这几个文件编译成一个动态库:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、动态库的链接
在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:
#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;
}
将test.c与动态库libtest.so链接生成执行文件test:
$ gcc test.c -L. -ltest -o test
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
$ ldd test
执行test,可以看到它是如何调用动态库中的函数的。
3、编译参数解析
最主要的是GCC命令行的一个选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号), 不用该标志外部程序无法连接。相当于一个可执行文件

-fPIC :表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

-L.:表示要连接的库在当前目录中

-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

在linux下可以用export命令来设置这个值, 在linux终端下输入:
export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:    
然后再输入:export   
即会显示是否设置正确   
export方式在重启后失效,所以也可以用 vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH变量。   
例如:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/au1200_rm/build_tools/bin。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql安装后在服务里找不到和服务启动不起来的解决方法

一,在安装完Mysql数据库后,发现在控制面板->管理->服务中找不到Mysql的服务启动 解决方法如下:开启命令行,按照如下步骤即可; 1.进入到mysql的安装包,在bin里执行:mysqld.exe -install …

WINFORM如何只弹出一个子窗体

public partial class Form1:Form{ Form2 fnull; public Form1() { InitializeComponent(); } private void Form1_Click(object sender, EventArg e) { if(fnull||f.IsDisposed) //注意先判断null,再判断IsDisposed,…

“指向指针的指针”的应用场景

结合以下博文来看。 值传递与地址传递的区别_天糊土的博客-CSDN博客 二维数组数和指针操作的理解_天糊土的博客-CSDN博客 “指针1”的理解_天糊土的博客-CSDN博客 多重指针操作_天糊土的博客-CSDN博客_多重指针 二重指针的应用场景 (1)用指针的指针指向指…

su root 和su - root 的区别

前几天,在一次项目中,犯了一个很低级的错误,但是没弄明白是什么问题。情况是这样的,我们在做灾备,重启系统化,以root用户权限,通过 su oracle ,进去后,oracle的rac 无法正…

弹出框

<!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equiv"Content-Type" content"text/html; charsetgb2312" /> <title>AlertBox 弹出层&#xff08;信息提示框&#xff09;效果&l…

一些Base64编码/解码及数据压缩/解压方面的知识

一.Base64编码/解码 一般用到的是Delphi自带的单元EncdDecd,当然还有第三方提供的单元或控件,其中我所接触到的认为比较好的有Indy的TIdMimeEncode / TIdMimeDecode组件,以及RjMime单元. 在这里主要想讲讲如何才能获得最好的编码/解码性能,EncdDecd提供了EncodeStream/DecodeSt…

easyUI 绑定右键菜单在数据行上显示

easyUI的显示数据的div都有一个样式,如下图 所有的表格都有一个datagrid-cell的样式那么这个时候我们就可以利用jquery来做时间的绑定了 下面是主要的js代码: /*绑定右键*/$(".datagrid-cell").live(contextmenu,function(e){//显示快捷菜单$(#mm).menu(show, {left:…

值传递与地址传递的区别

以下内容源于网络资源的学习与整理&#xff0c;欢迎交流。 总结 值传递&#xff0c;只是把原参的复制品传给形参&#xff0c;在子函数中修改这个形参&#xff0c;不会改变主函数中的原参。 地址传递&#xff0c;由于形参和原参表示同一个内容&#xff0c;在子函数中修改形参&a…

交叉编译器arm-linux-gcc

(一)交叉编译器简介 在一种计算机环境中运行的编译程序&#xff0c;能编译出在另外一种环境下运行的代码&#xff0c;这个编译过程就叫交叉编译.简单地说&#xff0c;就是在一个平台上生成另一个平台上的可执行代码. (二)体系结构与操作系统 (1)常见的体系结构有ARM结构、x86结…

web前端细解cookie那些事

web前端细解cookie那些事&#xff0c;在互联网时代&#xff0c;IT行业飞速发展&#xff0c;带动了web前端开发行业的兴趣。由于行业新兴起时间不久&#xff0c;专业人才缺乏&#xff0c;薪资待遇较高&#xff0c;已成为众多IT学子选择就业的首选&#xff0c;今天就为分享一些有…

一个很好的机器学习普及网站

1.介绍svm等算法深入浅出的网站 Free Mind 2.关于聚类算法的普及 A tutorial on Clustering Algorithm(中文翻译) 模糊聚类的应用--目标分割 exlusive clustering&#xff08;比如K-means) hierarchy clustering&#xff1a;先将 n 个样品各看成一类&#xff0c; 然后规定类与…

字符串处理示例--列车车次查询.sql

--列车车次信息数据表CREATE TABLE tb(col varchar(100))INSERT tb SELECT 1434/1/2/14UNION ALL SELECT "10653(85707)"UNION ALL SELECT "32608/7(83212/1)"UNION ALL SELECT "50057&#xff08;)"UNION ALL SELECT "T888&#xff08;备&…

查找算法的总结

声明&#xff1a;以下内容来源于网络资料的学习和整理 一、查找技术分类 1、静态查找表技术&#xff08;顺序查找、二分查找、分块查找&#xff09; 2、动态查找表技术&#xff08;二叉查找树&#xff09; 3、哈希表技术&#xff08;哈希表技术&#xff09; 二、查找技术说明…

一个C程序的编译过程(Linux环境下Gcc)

一 以下是C程序一般的编译过程&#xff1a; 从图中看到&#xff1a; 将编写的一个c程序&#xff08;源代码 &#xff09;转换成可以在硬件上运行的程序&#xff08;可执行代码 &#xff09;&#xff0c;需要进行编译阶段 和链接这两个阶段。 其中&#xff0c; 1. 编译阶段先通…

python3 django连接mysql 数据库

详情参考&#xff1a; https://blog.csdn.net/weixin_33127753/article/details/89100552 https://imshusheng.com/python/216.html 报错环境 python3.6&#xff0c;django2.2&#xff0c;PyMySQL0.9.3……django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or…

redis 主从复制 [转]

一、Redis的Replication&#xff1a; 这里首先需要说明的是&#xff0c;在Redis中配置Master-Slave模式真是太简单了。相信在阅读完这篇Blog之后你也可以轻松做到。这里我们还是先列出一些理论性的知识&#xff0c;后面给出实际操作的案例。 下面的列表清楚的解释了Redis…

动态查找表之二叉搜索树

一、二叉搜索树&#xff08;BST&#xff09; 二叉搜索树&#xff08;二叉排序树&#xff09;定义如下&#xff1a; &#xff08;1&#xff09;一棵空树&#xff1b; &#xff08;2&#xff09;或者不是空树&#xff1a; 1&#xff09;若左子树不空&#xff0c;则左子树上所有…

Mysql数据导入导出

导出导入数据库导出mysqldump方法mysqldump -u用户名 -p密码名 database [table]> 目标文件导入mysql -uroot -prootuse databasesource 目标文件&#xff1b;PS: 这种方法是导出整个表数据&#xff0c;并且带着建表信息&#xff0c;假如导入的数据库有同名的表&#xff0c;…

2-10 就业课(2.0)-oozie:9、oozie与hue的整合,以及整合后执行MR任务

5、hue整合oozie 第一步&#xff1a;停止oozie与hue的进程 通过命令停止oozie与hue的进程&#xff0c;准备修改oozie与hue的配置文件 第二步&#xff1a;修改oozie的配置文件&#xff08;老版本的bug&#xff0c;新版本已经不需要了&#xff09;这一步我们都不需要做了 修改ooz…

Screen Painter 程序设计

一、Screen 的创建及维护, TCode:SE51 输入程序名称&#xff0c;单击【建立】&#xff0c; 程序1000为SAP预留屏幕号&#xff0c;屏幕号必须定义1000外的其他数字&#xff0c;且最多不超过四位&#xff0c; 本例定义屏幕为SAP预留屏幕号为&#xff1a;100 * 属性设置&#xff1…