随着程序写的逐渐变多,或多或少的我们都会使用别人写好的库;或者我们不想让别人看到我们的一些核心程序,可以将核心程序封装成库。本次和大家分享的是在Ubuntu下使用Qt生成共享库以及在Qt中链接共享库的方法。

共享库是在Linux下的称呼,在Windows下被称为动态库。这块大家需要了解的是程序在编译时使用的库和程序在运行时使用的库需要一致,不然程序可能会闪退。而且运行时库的路径如果没有设置,那么系统就会在默认的路径下进行搜索,如果没找到程序直接就挂了。之后的文章会进行总结说明的。

程序平台: Ubuntu14.04、 Qt5.5.1

一、Qt 创建共享库

  1. 创建类型为库的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版本。

二、链接动态库

  1. 创建工程添加文件

创建一个继承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输入两个数字,点击按钮后通过共享库计算,如下:

三、后记总结

  1. 使用共享库问题与解决方法

以前在使用共享时,报了一个这样的错误:

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创建共享库与链接共享库详解的更多相关文章

  1. (转)Linux下PS1、PS2、PS3、PS4使用详解

    Linux下PS1.PS2.PS3.PS4使用详解 原文:http://www.linuxidc.com/Linux/2016-10/136597.htm 1.PS1——默认提示符 如下所示,可以通过 ...

  2. Linux下PS1、PS2、PS3、PS4使用详解

    参考印象笔记:

  3. Linux下weblogic10.3.6(jar)版本安装详解

    一.安装前的准备 安装weblogic是需要JDK环境的,虽然weblogic有自带的JDK,但是我一般是自己选择JDK进行安装,如果你要自行安装,可以参考我的另一篇博客 https://www.cn ...

  4. Linux下nagios网络监控与/proc/net/tcp文件详解

    问题描述:nagios自带的check_antp太过简约,除了状态统计输出外,什么参数都不提供.在面对不同应用服务器时,报警就成了很大问题. 问题描述:nagios自带的check_antp太过简约, ...

  5. Linux下Qt的安装与配置

    参考资料:http://www.cnblogs.com/emouse/archive/2013/01/28/2880142.html Linux 下编译.安装.配置 QT 下载qt 这里用的是4.7. ...

  6. Linux下多任务间通信和同步-mmap共享内存

    Linux下多任务间通信和同步-mmap共享内存 嵌入式开发交流群280352802,欢迎加入! 1.简介 共享内存可以说是最有用的进程间通信方式.两个不用的进程共享内存的意思是:同一块物理内存被映射 ...

  7. Linux下script命令录制、回放和共享终端操作script -t 2> timing.log -a output.session # 开始录制

    Linux下script命令录制.回放和共享终端操作 [日期:2018-09-04] 来源:cnblogs.com/f-ck-need-u  作者:骏马金龙 [字体:大 中 小]   另一篇终端会话共 ...

  8. Linux下c函数dlopen实现加载动态库so文件代码举例

    dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...

  9. Linux下SVN创建新的项目

    Linux下SVN创建新的项目   Linux环境下的SVN创建新的项目 一.前置条件: 1)有安装了linux系统的服务器,123.*.*.29 2)服务器上安装了svn,本人服务器的svn的数据安 ...

随机推荐

  1. python根据窗口标题找句柄,将窗口前置活动

    import time, threading, copy import win32api, win32con import win32gui import win32gui def zhaojb(aa ...

  2. 重拾javaweb(假期后第一次web测试)

    上学期通过十六周的时间,完成了javaweb的项目实践,其中包括很多次的练习以及测试.寒假时间大多用来挥霍,并没有对这些知识进行复习以及进一步的学习,所以在这场考试中,最终以八分的可怜成绩收尾,实在过 ...

  3. Leetcode4. 寻找两个正序数组的中位数

    > 简洁易懂讲清原理,讲不清你来打我~ 输入两个递增数组,输出中位数![在这里插入图片描述](https://img-blog.csdnimg.cn/25550994642144228e9862 ...

  4. 5Java基础整理

    1.API:Application programming interface 举例:System类中的 public static void arraycopy(int[] src,int srcP ...

  5. js里的发布订阅模式及vue里的事件订阅实现

    发布订阅模式(观察者模式) 发布订阅模式的定义:它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布订阅模式在JS中最常见的就是DOM的事件绑定与触发 ...

  6. 第十五篇 -- QListWidget与QToolButton(界面)

    效果图: 这还只是一个界面,并没有实现相应功能. 先看下这图的构成吧. 工具栏的就是将Action拖上去,这部分前面已经介绍过了,那就看下面这部分的构图. 1.左侧是一个工具箱(ToolBox)组件, ...

  7. Python基础之实现界面和代码分离

    第一步:用QT Designer画一个TreeWidget,存为treeview4.ui,这个处理前面TreeWidget那一节讲过,这里不细讲 treeview4.py # -*- coding: ...

  8. 用activiti实现类似钉钉审批流程-附整个系统源码

    前言 目前市场上有很多开源平台没有整合工作流,即使有,也是价格不菲的商业版,来看这篇文章的估计也了解了行情,肯定不便宜.我这个快速开发平台在系统基础功能(用户管理,部门管理-)上整合了工作流,你可以直 ...

  9. js 日期转为时间戳

    在js中,将一个字符转化成Date型也不是什么难事:var str = '2013-08-30'; // 日期字符串str = str.replace(/-/g,'/'); // 将-替换成/,因为下 ...

  10. 获取不到自定义的request的header属性

    java获取headers的代码如下: // 获取http-header里面对应的签名信息 Enumeration<?> headerNames = request.getHeaderNa ...