QT 静态库和动态库的使用方法

QT 静态库和动态库的使用方法


背景知识:程序在编译成可执行文件时,会有四步过程:
1预处理(头文件和宏定义) g++ -E 1.cpp -o 1.i
2编译 将c代码编译成汇编代码 g++ -S 1.cpp -o 1.s
3汇编 将汇编代码编译成二进制代码 g++ -c 1.cpp -o 1.o
4链接 链接我们用到的函数代码 还有地址(包含静态库而动态库是在运行时链接) gcc 1.c
静态库:在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系;
动态库:在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。

一 Qt创建静态库:
1.点击New Project ->Library ->C++库 点击choose
QT 静态库和动态库的使用方法
2.在类型选择静态链接库,点击下一步。QT 静态库和动态库的使用方法
3.然后一直点击下一步。

代码如下:
Lib.h
#include “lib.h”

Lib::Lib()
{
}
long Lib::add(int a, int b)
{
return a+b;
}
Lib.cpp
#include “lib.h”

Lib::Lib()
{
}
long Lib::add(int a, int b)
{
return a+b;
}
编译后会生成Lib.o和Lib.a文件。
Lib.o:是我们生成的二进制过程文件。
Lib.a:这就是我们的静态库文件。
二:Qt静态库调用
新建widget工程
pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
lib.h
FORMS += mainwindow.ui
LIBS += -L$$PWD/./ -lLib
注意:链接的时候不用后缀(.a)。
把Lib.h和Lib.a放到我们的程序目录中。把Lib.h添加到工程。把Lib.a添加到工程中。
三 Qt创建动态库
新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sharedlib)
QT 静态库和动态库的使用方法
生成的目录结构如图:
QT 静态库和动态库的使用方法
修改 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

Sharedlib::Sharedlib()
{
}

void Sharedlib::test()
{
QMessageBox::warning(0, “Sharedlib::test”, “Sharedlib::test”);
}

int add(int a, int b)
{
return a+b;
}
四 Qt动态库调用分为两种方式。
第一种方式:需要h、a和dll文件。
h为接口头文件。
a为接口转换文件,把你调用接口转换到dll上。
dll为动态库。
这种方式比较简单直接使用,代码量少(需要把a和dll放在一起)。在pro文件中导入a。
工程文件片段:
HEADERS += mainwindow.h
untitled2.h
share.h
win32: LIBS += -L$$PWD/./ -lShare

INCLUDEPATH += PWD/.DEPENDPATH+=PWD/. DEPENDPATH += PWD/.
第二种方式:只需要h和dll文件。
1.需要在动态库里面写一个C函数,不然没办法获取对象。还要让编译器指定让C编译器编译。注意还必须把成员函数写成虚函数才能调用(我也不知道为什么,谁知道给我留言谢谢)。
如下:
头文件:
class Share
{

public:
Share();
virtual long add(int,int);
virtual void minus();
};
typedef Share* (Obj)();
extern “C”
{
Share * CreatObj();
}
CPP文件:
#include “Share.h”
#include
Untitled2
CreatObj()
{
static Obj = NULL;
if(Obj)
{
return Obj;
}
else
{
return Obj = new Share;
}
}
Share::Share()
{
}
long Share::add(int a,int b)
{
return (long)a+b;
}
void Share::minus()
{
qDebug()<<“minus”;
}
总结:
静态库调用:把Lib.h和Lib.a放到我们的程序目录中。把Lib.h添加到工程。把Lib.a添加到工程中。
动态库调用一:需要h、a和dll文件。
动态库调用二:需要h和dll文件,要在库里面写C接口获取对象(因为C++编译器会把函数的参数名编译进函数,为了支持重载)。