前言: 编译器 Qt Creator, 系统环境 win7 64 位

1.创建共享库:

新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sharedlib)

生成的目录结构如图:

修改 sharedlib.h 中的代码:

// sharedlib.h
#ifndef SHAREDLIB_H
#define SHAREDLIB_H #include "sharedlib_global.h" class SHAREDLIBSHARED_EXPORT Sharedlib// 导出类, 客户端可直接加载
{ public:
Sharedlib();
void test();
}; extern "C" Q_DECL_EXPORT int add(int a, int b);//导出函数, 客户端可用 QLibrary 加载 #endif // SHAREDLIB_H

修改 sharedlib.cpp 中的代码:

// sharedlib.cpp
#include "sharedlib.h" #include <QMessageBox> Sharedlib::Sharedlib()
{
} void Sharedlib::test()
{
QMessageBox::warning(0, "Sharedlib::test", "Sharedlib::test");
} int add(int a, int b)
{
return a+b;
}

2.调用共享库(方式一):

新建文件或项目->选择 Application, Qt Console Application->项目名为 app1->下一步

修改客户端程序 main.cpp 中的代码:

// main.cpp
#include <QCoreApplication>
#include <QLibrary>
#include <iostream>
using namespace std; int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); typedef int (*Add)(int a, int b); QLibrary mylib("sharedlib.dll"); if(!mylib.load()){// 加载 dll 失败
cout<<"加载 sharedlib.dll 失败!"<<endl;
return -1;
}
Add add = (Add)mylib.resolve("add");
if(0 == add){// 加载失败
cout<<"加载函数 add 失败!"<<endl;
return -1;
} int sum = add(1,2);// 调用 add 函数 cout<<sum<<endl; return 0; return a.exec();
}

编译 sharedlib 工程和 app1 工程-> 将生成的 sharedlib.dll 文件复制到 app1.exe 所在目录中->运行 app1.exe 输出 3

总结:这种调用方式需要在客户端程序编译时需要提供 .dll 的名字信息及其函数信息, 需要在客户端程序运行时提供 .dll 文件, 客户端中要写的代码较多.

3.调用共享库(方式二):

新建文件或项目->选择 Application, Qt QWidgets Application->项目名为 app2->下一步

在 app2.pro 文件最后添加如下代码, 用来说明 sharedlib.lib 的路径信息:

unix|win32: LIBS += -L$$PWD/../build-sharedlib-unknown-Debug/debug/ -lsharedlib

INCLUDEPATH += $$PWD/../build-sharedlib-unknown-Debug/debug
DEPENDPATH += $$PWD/../build-sharedlib-unknown-Debug/debug

将 sharedlib 工程源码目录下的 sharedlib.h 和 sharedlib_global.h 头文件复制到 app2 工程源码目录下, 将 sharedlib.dll 文件复制到 app2.exe 所在目录中

修改客户端程序 main.cpp 中的代码:

// main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "sharedlib.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// MainWindow w;
// w.show();
Sharedlib sb;
sb.test(); return a.exec();
}

编译 app2 工程, 运行 app2.exe, 弹出如图对话框, 表示程序正确执行:

总结: 这种调用方式需要在客户端程序编译时提供 .lib 和 .h 文件, 需要在客户端程序运行时提供 .dll 文件,  客户端中要写的代码较少.

4.方式一和方式二调用共享库的异同点:

客户端程序运行时都是只需要 .dll 文件; 编译时有些差别, 方式一代码较多, 但无需 .lib 和 .h 文件, 方式二代码简单(和调用普通类一样), 但是需要 .lib 和 .h 文件.

创建好三个项目后的文件结构如图:

5. 静态链接库的创建:

新建文件或项目->选择 Library 和 c++ 库->选择静态链接库->下一步(工程名为 staticdlib)

修改 staticlib.h 中的代码:

// staticlib.h
#ifndef STATICLIB_H
#define STATICLIB_H class Staticlib
{ public:
Staticlib();
void test();
}; #endif // STATICLIB_H

修改 staticlib.cpp 中的代码:

// staticlib.cpp
#include "staticlib.h"
#include <iostream>
using namespace std; Staticlib::Staticlib()
{
cout<<"Staticlib::Staticlib"<<endl;
} void Staticlib::test()
{
cout<<"Staticlib::test"<<endl;
}

编译工程之后会生成 staticlib.lib 文件

6. 调用静态链接库:

新建文件或项目->选择 Application, Qt Console Application->项目名为 app->下一步

在 app.pro 文件最后添加如下代码, 用来说明 staticlib.lib 的路径信息:

unix|win32: LIBS += -L$$PWD/../build-staticlib-unknown-Debug/debug/ -lstaticlib

INCLUDEPATH += $$PWD/../build-staticlib-unknown-Debug/debug
DEPENDPATH += $$PWD/../build-staticlib-unknown-Debug/debug

将 staticlib 工程目录下的 staticlib.h 复制到 app 工程目录下

修改客户端程序 main.cpp 中的代码:

// main.cpp
#include <QCoreApplication>
#include "staticlib.h" int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); Staticlib sb;
sb.test(); return a.exec();
}

编译 app 工程, 生成 app.exe 文件, 运行 app.exe 文件, 输出如图:

总结: 客户端程序编译时需要 .h 和 .lib 文件, 运行时无需其它文件.

7. 共享库(动态链接库)和静态链接库的异同点:

异: 调用共享库的客户端运行时需要 .dll 文件, 静态链接库的不需要;

库程序发生改变时, 共享库客户端只需更新 .dll 文件, 静态链接库客户端需要重新编译.

同: 都可用于多模块共同开发程序

注: 本文是原创文章, 欢迎咨询或提出修改意见, 联系方式QQ:1871046323@qq.com

源码地址: https://github.com/ZhangShuaiH/QT/tree/master/demos/lib

Qt 共享库(动态链接库)和静态链接库的创建及调用的更多相关文章

  1. Linux下动态链接库和静态链接库

    第一部分:编译过程 先了解一下linux下C代码的编译过程,C代码的编译,一般分成四个阶段,包括:预编译,编译,汇编和链接,这四个阶段的分工是 预处理过程,负责头文件展开,宏替换,条件编译的选择,删除 ...

  2. [转载]GCC 编译使用动态链接库和静态链接库--及先后顺序----及环境变量设置总结

    来自http://blog.csdn.net/benpaobagzb/article/details/51364005 GCC 编译使用动态链接库和静态链接库 1 库的分类 根据链接时期的不同,库又有 ...

  3. 利用GCC编译器生成动态链接库和静态链接库

    转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...

  4. GCC 编译使用动态链接库和静态链接库的方法

    1 库的分类 依据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的.所以生成的可执行文件就不受库的影响了.即使库被删除了,程序依旧能够成功执行. 有别于静态库,动态库的链接是在程 ...

  5. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  6. C# - *.dll vs *.lib (动态链接库 vs 静态链接库)

    静态库 库(Library)就是一段编译好的二进制代码,加上头文件就可以使用. 静态链接库(Windows 下的*.lib, Linux & Mac 下的 .a).之所以叫做静态,是因为静态库 ...

  7. linux动态链接库和静态链接库

    Linux下静态链接库与动态链接库的区别 引言 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件 (object file)与牵涉到的函数库(librar ...

  8. Windows 下动态链接库和静态链接库

    1.静态链接库:就是在编译的时候把库中代码复制进工程中,导致工程变大,但是速度快. 缺点在于一套代码可能在内存中有多份拷贝,占用内存. 2.动态链接库:库由windos api加载库代码,内存中只有一 ...

  9. GCC 编译使用动态链接库和静态链接库

    1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...

随机推荐

  1. lua的通用print函数

    1.前言 最近在做关于openresty方面的工作,涉及到lua脚本语言,经常需要打日志查看内容.普通的print函数遇到nil或table时,非常无力.而项目中的代码经常遇到参数为nil或table ...

  2. 解决mysql漏洞 Oracle MySQL Server远程安全漏洞(CVE-2015-0411)

    有时候会检测到服务器有很多漏洞,而大部分漏洞都是由于服务的版本过低的原因,因为官网出现漏洞就会发布新版本来修复这个漏洞,所以一般情况下,我们只需要对相应的软件包进行升级到安全版本即可. 通过查阅官网信 ...

  3. windows下查看端口占用情况及关闭相应的进程

    经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,如何知道谁占有了我们需要的端口,很多人都比较头疼,下面就介绍一种非常简单的方法. 例如:需要查看9001端口被谁占用,并将其进程强制关闭 在 ...

  4. java多线程(一)-概述

    最近这段在看java多线程编程方面的东西.所以特写了几篇文章,来总结和回顾一下自己所学习到的相关知识.因为水平有限,文章中总结不全面甚至理解错误的地方,欢迎读者指点批评. 我们平时所接触到的程序,都是 ...

  5. MyEclipse 2015利用Cygwin+CDT搭建C/C++开发环境

    GitHub原文:https://github.com/x113773/testall/issues/22 首先安装Cygwin 1:首先去网站 www.cygwin.com 下载 Cygwin 的 ...

  6. 【图文】如何在centos上安装tomcat

    先到tomcat官网下载安装包(随便下载你想要的版本) 假设你现在使用的是windows系统 那么就把你下载来的压缩包解压,放到一个目录中 在你本地的windows系统中安装个xshell和xftp ...

  7. icon图标和文字整体居中在button按钮

    icon图标和文字整体居中在button按钮 icon图标和文字整体居中 一般我们常做的button按钮是文字居中 现在这个需要icon图标和文字一起居中在背景色 <a href="# ...

  8. 常用base.css

    ul { list-style: none;}a { text-decoration: none;} body,h1,h2,h3,h4,h5,h6,p,ul,ol,form { margin: 0; ...

  9. linux 实时同步inotify

    #实时同步inotify 1.inotify简介inotify是一种强大的,细腻度的,异步的文件系统事件监控机制,linux内核从2.6.13起,加入了inotify支持,通过INOTIFY可以监控文 ...

  10. 转JS--通过按钮直接把input或者textarea里的值复制到粘贴板里

    document.activeElement属性为HTML 5中新增的document对象的一个属性,该属性用于返回光标所在元素.当光标未落在页面中任何元素内时,属性值返回body元素. setSel ...