目录
Qt DLL总结【一】-链接库预备知识
Qt DLL总结【二】-创建及调用QT的 DLL
Qt DLL总结【三】-VS2008+Qt 使用QPluginLoader访问DLL
开发环境:VS2008+Qt4.7.4
最近看了不少Qt的DLL例子,总结一下如何创建和调用QT 动态链接库。
先讲一下对QT动态链接库的调用方法,主要包括:
1、显式链接DLL,调用DLL的全局函数,采用Qt的QLibrary方法
2、显示链接DLL,调用DLL中类对象、成员函数。(通过对象即可实现类成员函数的调用)
①用虚函数表的方法,这也是COM使用的方法,利用Qt的QLibrary技术调用;
②用GetProcAddress直接调用。
③用Qt的QPluginLoader类直接调用生成的DLL插件类对象
3、隐式链接DLL:也是采用Qt的Qlibrary方法
关于这种三种方法,下面详细叙说
详细分类叙述
前提:两个项目文件目录
1、TestDLL项目:testdll_global.h,TestDll.h,TestDll.cpp
2、TestMain exe应用项目:main.cpp
testdll_global.h 文件源代码一直不变
#ifndef TESTDLL_GLOBAL_H
#define TESTDLL_GLOBAL_H
#include <QtCore/qglobal.h>
#ifdef TESTDLL_LIB
# define TESTDLL_EXPORT Q_DECL_EXPORT
#else
# define TESTDLL_EXPORT Q_DECL_IMPORT
#endif
#endif // TESTDLL_GLOBAL_H
DLL的显式链接在某些时候比隐式链接具有更大的灵活性。比如,如果在运行时发现DLL无法找到,程序可以显示一个错误信息并能继续运行。当你想为你的程序提供插件服务时,显式链接也很有用处
1、采用显示链接,调用DLL中全局函数,只需要一个TestDLL.dll。
通常Windows下程序显示调用dll的步骤分为三步(三个函数):LoadLibrary()、GetProcAdress()、FreeLibrary()
其中,LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)
GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用
FreeLibrary() 释放dll所占空间
而QT的QLibrary类显示链接调用DLL的步骤:load()、resolve(const char * symbol )、unload()和VC步骤类似
TestDll.dll项目中的TestDLL.h源码
#ifndef TESTDLL_H
#define TESTDLL_H
#include "testdll_global.h"
class TESTDLL_EXPORT TestDll
{
public:
TestDll();
~TestDll();
private:
};
extern "C" TESTDLL_EXPORT void helloWorld();
extern "C" TESTDLL_EXPORT int add(int a,int b);
#endif // TESTDLL_H
TestDll.dll项目中的TestDLL.cpp源码
#include <iostream>
#include "TestDll.h"
TestDll::TestDll()
{
}
TestDll::~TestDll()
{
}
void helloWorld()
{
std::cout << "hello,world!";
}
int add(int a,int b)
{
return a + b;
}
注:1)建立成功DLL项目后,可以在VS命令提示行中用命令"dumpbin -exports DllTest.dll"来查看(也可以用VC工具包中的depends使用程序来查看)
注:2)必须使用extern "C"链接标记,否则C++编译器会产生一个修饰过的函数名,这样导出函数的名字将不再是helloworld,而是一个形如" ?helloWorld@TestDll@@UAEXXZ”的名字。为什么名字不是helloworld呢?这是因为C++为了支持函数的重载,会在编译时将函数的参数类型信息以及返回值类型信息加入到函数名中,这样代码中名字一样的重载函数,在经过编译后就互相区分开了,调用时函数名也经过同样的处理,就能找到对应的函数了。详细可以看这篇文章动态链接库(Dynamic Link Library)学习笔记
TestMain项目 main.cpp
#include <QtCore/QCoreApplication>
#include <iostream>
#include <QLibrary>
typedef int (*Fun)(int,int); //定义函数指针,int add(int a,int b);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLibrary mylib("TestDll.dll"); //声明所用到的dll文件
int result;
//判断是否正确加载
if (mylib.load())
{
std::cout << "DLL load is OK!"<<std::endl;
//调用外部函数 add()
Fun add = (Fun)mylib.resolve("add");
//是否成功连接上 add() 函数
if (add)
{
std::cout << "Link to add Function is OK!"<<std::endl;
//这里函数指针调用dll中的 add() 函数
result = add(5,6);
std::cout << result;
}
else
std::cout << "Link to add Function failed!!"<<std::endl;
}
//加载失败
else
std::cout << "DLL is not loaded!"<<std::endl;
return a.exec();
}
2、采用显示链接,调用C++类中的类对象、成员函数
如果你想导出并显式链接一组C++类中的成员函数又该怎么办呢?这里有两个问题。第一是C++成员函数名是经过修饰的(即使指定extern "C"标记也是这样);第二是C++不允许将指向成员函数的指针转换成其它类型。这两个问题限制了C++类的显式链接。下面介绍两种方法来解决这个问题:
①用虚函数表的方法,这也是COM使用的方法,利用Qt的QLibrary技术调用;
②用GetProcAddress直接调用。
③用Qt的QPluginLoader类直接调用生成的DLL插件类对象
①虚函数表的方法,QLibrary 技术调用
TestDll.h代码
#ifndef TESTDLL_H
#define TESTDLL_H
#include "testdll_global.h"
class TESTDLL_EXPORT TestDll
{
public:
TestDll();
virtual~TestDll();
virtual void helloWorld(); //类成员函数
private:
};
extern "C" TESTDLL_EXPORT TestDll* getTestDll(); //获取类TestDll的对象
#endif // TESTDLL_H
TestDll.cpp源码
#include <iostream>
#include "TestDll.h"
TestDll::TestDll()
{
}
TestDll::~TestDll()
{
}
void TestDll::helloWorld()
{
std::cout << "hello,world!";
}
TestDll* getTestDll()
{
return new TestDll();
}
TestMain项目中的main.cpp源码
#include <QtCore/QCoreApplication>
#include <iostream>
#include <QLibrary>
#include "../TestDll/TestDll.h" //头文件还是需要加的,否则无法解析TestDll类
typedef TestDll* (*GetTestDll)();//定义函数指针,获取类TestDLL对象;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLibrary mylib("TestDll.dll"); //声明所用到的dll文件
int result;
//判断是否正确加载
if (mylib.load())
{
GetTestDll getTestDll = (GetTestDll)mylib.resolve("getTestDll");
if(getTestDll)
{
TestDll *testDll = getTestDll();
testDll->helloWorld();
delete testDll;
}
}
//加载失败
else
std::cout << "DLL is not loaded!"<<std::endl;
return a.exec();
}
这个方法的使用得用户可以很容易地为你的程序制作插件。它的缺点是创建对象的内存必须在dll中分配
②用GetProcAddress直接调用类对象中的成员函数
这个方法,我没测试,对我没对大作用,还得用def导出DLL函数,有兴趣的就参考一下这篇文章。DLL中类的显式链接
③用Qt的QPluginLoader类直接调用生成的DLL插件类对象
这个方法,我单独写一篇总结,请看QPluginLoader的简单小例子VS2008+Qt 使用QPluginLoader访问DLL
3、采用隐式链接方法,通过QLibrary类对DLL中类对象、全局函数的调用
TestDll.h
#ifndef TESTDLL_H
#define TESTDLL_H
#include "testdll_global.h"
class TESTDLL_EXPORT TestDll
{
public:
TestDll();
~TestDll();
void helloWorld(); //类成员函数
private:
};
extern "C" TESTDLL_EXPORT int add(int a,int b); //自定义的外部函数
#endif // TESTDLL_H
TestDll.cpp源码
#include <iostream>
#include "TestDll.h"
TestDll::TestDll()
{
}
TestDll::~TestDll()
{
}
void TestDll::helloWorld()
{
std::cout << "hello,world!";
}
int add(int a,int b)
{
return a + b;
}
TestMain项目中的main.cpp ,需要稍微配置头文件和lib文件
1、在项目中主程序引入TestDll.h头文件,
2、配置项目属性:加入TestDLL.lib的文件目录,在Linker/General/Additional Library Diretories里面选择TestDll.lib的文件目录D:\VSWorkSpace\Test\Debug
3、配置项目属性:加入TestDll.lib文件,在Linker/Input/Additional Dependencies 中加入 TestDll.lib
main.cpp源码
#include <QtCore/QCoreApplication>
#include <iostream>
#include <QLibrary>
#include "../TestDll/TestDll.h"
//引入TestDll.lib文件,和上面的2,3步工作同理
//#pragma comment(lib, "../Debug/TestDll.lib")
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int result = add(5,6);
std::cout << result;
TestDll dll;
dll.helloWorld();
return a.exec();
}
结果即可编译成功
分享到:
相关推荐
编写QT的dll,QT调用QT的dll,QT调用外部的dll,MFC程序调用QT的dll,
QT创建与调用Dll方法(包括类成员)--显式调用 http://www.cnblogs.com/lomper/p/4112626.html
C# 与 Qt 混合编程,开发软件。 Qt编写功能模块给C#调用。...这个例子是一个完整的播放器例子,也就是Qt+mpv开发视频播放器给C#调用,主要是介绍Qt编译成DLL,导出接口给C#调用整体流流程,以及接口使用。
将QT界面做成dll在qt其他程序中调用,
C#调用QT的dll方法,个人资料方法,仅供参考,如有哪位大虾有更好的方法,请留言
qt dll调用实例, qt dll调用实例 注意工程配置,我的开发环境为qt creator 4.84+mingw.exe
qtdll dll" ] public static extern int add int i ; 第三步:调用函数执行; Console WriteLine add 10 ToString ; 2:QT 第一步:引入头文件; #include <QLibrary> 第二步:定义函数指针 以备调用; ...
该资源主要介绍如何在Qt中调用C++动态链接库,包括一个动态链接库文件和一个Qt应用程序。相关的博文介绍了该资源调用的具体方法和步骤,需要可以参考鄙人文章《QT 调用外部C++动态链接库方法》
c#调用QTdll的框架(包含案例),可以成功运行,自己创建一个C#窗口程序就可以调用, 调用的时候别忘了将dll所依赖的dll放在同一目录下,否则会报试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)。
该资源能够使用qt生成dll, 同时又mfc dll的例程,同时有使用qt调用 mfc 和qt dll的例程 。对于 学习使用qt dll很有帮助。
build-qtdll-Desktop_Qt_5_12_2_MSVC2015_64bit-Release文件夹是qt编译生成的文件夹;QtReleaseDll文件夹里面是最重要的qtdialog.dll以及他所依赖的所有的库;CsharpUseQtDll文件夹里面是c#工程。 具体使用细节参见...
Qt 调用 DLL功能函数是本文要介绍的内容,DLL 是一个包含可由多个程序同时使用的代码和数据的库
dll的创建及调用
调用dll里的全局函数,使用QLibrary,它封装了loadlibrary和getprocaddress,等 freelibrary 要求: 需要知道dll里函数的原型,来写函数指针。 dll放到一个指定的目录下不一定非exe旁边。 DLL_CALL2: 调用dll里...
通过使用Qt开发框架,生成dLL动态库,供MFC执行程序调用。实现MFC调用Qt界面显示。
两种接口的使用 1. 返回类型为int的简单add函数 2. 回调函数
第二部分是 QT在 linux 上 DLL(os)的导出和调用; /////////////////////////////////////////////////////////////////////////////////////////////////////////////Windows///////////////////////////////...
delphi可以很方便的封装第三方库,导出dll,此方法可以很方便的生成供Qt或VC调用的Lib文件,免去动态加载的麻烦,喜欢的朋友可以试下。我就是这么用的。
需要QT程序生成dll供MFC或C#调用时,可以参考...可以参考路径:qtwinmigrate\examples\qtdll\ 。 资源还包含了MFC等源码。 需要qtwinmigrate.pri的,可以在路径:qtwinmigrate\src\qtwinmigrate.pri,提供支持。
将Qt控件和窗口封装进dll中,并使用MFC和Qt应用程序写出demo来调用该dll。将dll中封装的Qt窗口嵌入到主程序中,实现窗口渲染和消息传递。