Linux下Qt创建共享库与链接共享库详解
随着程序写的逐渐变多,或多或少的我们都会使用别人写好的库;或者我们不想让别人看到我们的一些核心程序,可以将核心程序封装成库。本次和大家分享的是在Ubuntu下使用Qt生成共享库以及在Qt中链接共享库的方法。
共享库是在Linux下的称呼,在Windows下被称为动态库。这块大家需要了解的是程序在编译时使用的库和程序在运行时使用的库需要一致,不然程序可能会闪退。而且运行时库的路径如果没有设置,那么系统就会在默认的路径下进行搜索,如果没找到程序直接就挂了。之后的文章会进行总结说明的。
程序平台: Ubuntu14.04、 Qt5.5.1
一、Qt 创建共享库
- 创建类型为库的Qt工程
① 新建工程-> Library -> C++ 库:
②类型选择默认的共享库,填写名称并选择工程路径。简单说下库的类型分别是动态库、静态库和Qt的插件
③选择默认的套件即可
④选择所需模块,这里我没有勾选任何模块
⑤设置类的基本信息
⑥完成向导
2.工程文件
①工程创建完成后,删掉了Qt生成的一些文件,文件目录如下
② .pro 文件的修改,添加版本号的设置
QT -= core gui
TARGET = TestLib
TEMPLATE = lib
VERSION += 1.1.0
CONFIG += debug_and_release
CONFIG(debug, debug|release) {
unix: TARGET = $$join(TARGET,,,_debug)
else: TARGET = $$join(TARGET,,,d)
}
DEFINES += TESTLIB_LIBRARY
SOURCES += addlib.cpp
HEADERS += addlib.h
unix {
target.path = /usr/lib
INSTALLS += target
}
TARGET : 库的名称
TEMPLATE :模板类型,类型为lib ,即生成的是一个库文件
VERSION(新增部分) :库的版本号设置
CONFIG (新增部分) :控制编译的Debug与Release库的版本名称
3.生成共享库
该共享库实现了计算两个整型数和的功能,过于简单,莫要介意~
①.h文件内容
#ifndef ADDLIB_H
#define ADDLIB_H
class AddLib
{
public:
AddLib();
int myAdd(int x, int y);
};
#endif // ADDLIB_H
②.cpp内容
#include "addlib.h"
AddLib::AddLib()
{
}
int AddLib::myAdd(int x, int y)
{
return x + y;
}
③构建与运行
只构建的话就会直接生成共享库,如果运行的话就是下面这个样子。
④生成动态库效果
到这里我们就已经生成好了动态库,可以看下我们添加的动态库的版本号。
注意,我这里没有区分Debug与Release版本。
二、链接动态库
- 创建工程添加文件
创建一个继承QWidget的应用程序后,在与.pro文件同级目录下添加一个如下目录组织的文件:
main.cpp
***.pro
Lib/
test/
linux_x32/
Include/
addlib.h
lib/
libTestLib.so**
2.借助Qt添加库
①右键项目->添加库
②选择链接库的类型,选择【外部库】
③选择链接库的路径与平台等信息
①.pro中新增文件
unix:!macx: LIBS += -L$$PWD/Lib/test/linux_x32/lib/ -lTestLib
INCLUDEPATH += $$PWD/Lib/test/linux_x32/include
DEPENDPATH += $$PWD/Lib/test/linux_x32/include
$$PWD :用于指定包含.pro文件目录的完整路径
INCLUDEPATH :指定了编译项目时被搜索到的 #include 目录
LIBS :指定了链接到项目中库的列表
④修改后的.pro文件
实际项目中我们的库可能会用到多个平台,所以一般创建如下
unix{
contains(QT_ARCH, i386){
INCLUDEPATH += $$PWD/Lib/test/linux_x32/include
LIBS += -L$$PWD/Lib/test/linux_x32/lib -lTestLib
}
contains(QT_ARCH, x86_64){
}
}else{
contains(QT_ARCH, i386){
}
contains(QT_ARCH, x86_64){
#64bit
}
}
3.测试程序的编写
①.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "addlib.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pbn_testAddLib_clicked();
private:
Ui::Widget *ui;
AddLib m_addLib;
};
#endif // WIDGET_H
② .cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pbn_testAddLib_clicked()
{
int x = ui->le_x->text().toInt();
int y = ui->le_y->text().toInt();
int ret = m_addLib.myAdd(x,y);
ui->le_ret->setText(QString::number(ret));
qDebug() << "add ret is :" << ret;
}
③ UI输入两个数字,点击按钮后通过共享库计算,如下:
三、后记总结
- 使用共享库问题与解决方法
以前在使用共享时,报了一个这样的错误:
error while loading shared libraries: libTestLib.so.1: cannot open shared object file: No such file or directory
加载共享库时失败,没找到。那会儿的解决办法是把共享库拷贝到 usr/local/lib下,这样问题就没有了,拷贝后要使用ldconfig命令。
上面的错误是在运行时没有找到共享库,在Linux下,可以使用 ldd命令查看一个可执行程序所需的库,效果如下:
2.为什么在Qt中运行没有报上面的错误?
由于以前使用共享库遇到过上面的问题,但是在刚刚测试共享库的时候,为什么没有报错呢?是Qt将生成的共享库放到Linux默认的搜索路径下了么?
于是我使用了locate +库名 命令进行搜索,但是并没有在其他路径下发现刚刚生成的共享库;于是我又去找配置Linux环境变量的文件,发现也没有。root下,在/etc/ld.so.conf.d文件下查看。
然鹅我并没有放弃,于是借助谷歌,搜索了下相关问题【Qt 编译工程的过程】,虽然没有找到答案,但是发现了一些线索:
在Projects中的Run Environment 下的LD_LIBRARY_PATH对应的Value里面,我看到了在程序中链接库的目录。至此,我觉得我找到了原因。
3.小结中的小结
通过对一个问题的求解,我们顺藤摸瓜的会学习到很多其他知识。像本次就知道几个Linux命令的使用场景。
欢迎大家关注公众号 : Pou光明
如需工程源码可在后台留下邮箱或其他联系方式
Linux下Qt创建共享库与链接共享库详解的更多相关文章
- (转)Linux下PS1、PS2、PS3、PS4使用详解
Linux下PS1.PS2.PS3.PS4使用详解 原文:http://www.linuxidc.com/Linux/2016-10/136597.htm 1.PS1——默认提示符 如下所示,可以通过 ...
- Linux下PS1、PS2、PS3、PS4使用详解
参考印象笔记:
- Linux下weblogic10.3.6(jar)版本安装详解
一.安装前的准备 安装weblogic是需要JDK环境的,虽然weblogic有自带的JDK,但是我一般是自己选择JDK进行安装,如果你要自行安装,可以参考我的另一篇博客 https://www.cn ...
- Linux下nagios网络监控与/proc/net/tcp文件详解
问题描述:nagios自带的check_antp太过简约,除了状态统计输出外,什么参数都不提供.在面对不同应用服务器时,报警就成了很大问题. 问题描述:nagios自带的check_antp太过简约, ...
- Linux下Qt的安装与配置
参考资料:http://www.cnblogs.com/emouse/archive/2013/01/28/2880142.html Linux 下编译.安装.配置 QT 下载qt 这里用的是4.7. ...
- Linux下多任务间通信和同步-mmap共享内存
Linux下多任务间通信和同步-mmap共享内存 嵌入式开发交流群280352802,欢迎加入! 1.简介 共享内存可以说是最有用的进程间通信方式.两个不用的进程共享内存的意思是:同一块物理内存被映射 ...
- Linux下script命令录制、回放和共享终端操作script -t 2> timing.log -a output.session # 开始录制
Linux下script命令录制.回放和共享终端操作 [日期:2018-09-04] 来源:cnblogs.com/f-ck-need-u 作者:骏马金龙 [字体:大 中 小] 另一篇终端会话共 ...
- Linux下c函数dlopen实现加载动态库so文件代码举例
dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...
- Linux下SVN创建新的项目
Linux下SVN创建新的项目 Linux环境下的SVN创建新的项目 一.前置条件: 1)有安装了linux系统的服务器,123.*.*.29 2)服务器上安装了svn,本人服务器的svn的数据安 ...
随机推荐
- Django基础008--model多对多
1.多对多表结构设计 class Student(models.Model): name = models.CharField(verbose_name='学生名字',max_length=100) ...
- 前端开发入门到进阶第三集【JavaScript中如何将html字符串转化为Jquery对象或者Dom对象】
https://www.cnblogs.com/mingjiatang/p/4746845.html
- 【C#】C#中使用GDAL3(一):Windows下超详细编译C#版GDAL3.3.0(VS2015+.NET 4+32位/64位)
转载请注明原文地址:https://www.cnblogs.com/litou/p/15004877.html 目录 一.介绍 二.编译准备 三.编译SQLite 四.编译LibTiff 五.编译PR ...
- P2476-记忆化搜索
链接 DP? 我们看看,这个状态似乎有亿点点多. 我们看看数据范围,数量不超过5,颜色数不超过15. 15维DP显然不靠谱. 那么我们就思考一下--个数? 记忆化搜索可ac: #include< ...
- 选择排序(selection_sort)——Python实现
# 选择排序 # 作用:对给出的n个顺序不定的数进行排序 # 输入:任意数组A # 输出:按顺序排列的数组A # 时间复杂度 (n(n-1))/2 # 选择排序 # 第一趟:选择第一个元素,依次与 ...
- SQL_之 递归_START WITH id ='102' CONNECT BY PRIOR pid=id
oracle 递归用法 SELECT * FROM menu START WITH id ='102' CONNECT BY PRIOR pid=id 一种应用 SELECT * FROM menu ...
- js学习笔记之在数组中删除重复的元素自保留一个
遍历要删除的数组arr, 把元素分别放入另一个数组tmp中,在判断该元素在arr中不存在才允许放入tmp中 <script type="text/javascript"> ...
- sql server 查看数据库配置等信息(字符集,编码格式,版本号...)
select SERVERPROPERTY(N'edition') as Edition --数据版本,如企业版.开发版等,SERVERPROPERTY(N'collation') as Collat ...
- fastbin attack学习小结
fastbin attack学习小结 之前留在本地的一篇笔记,复习一下. 下面以glibc2.23为例,说明fastbin管理动态内存的细节.先看一下释放内存的管理: if ((unsigned ...
- C++ //多态案例三 ---电脑组装
1 //多态案例三 ---电脑组装 2 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 7 ...