看网上的好多关于QT调用Dll的方法,大部分都是调用函数的,并没有调用C++类成员的情况,即使是有,比如说:

Qt 一步一步实现dll调用(附源码)---(这一篇里没有调用类成员的)

Qt调用dll中的功能函数

​我就是按照这上面的教程一步步做的,可惜了都没成功~~~这里面都有一个最重要的步骤没有说清楚(可能怪我笨~~),路径问题!!!

所以这里自我做一下总结:

创建时选择C++ Library就可以了,然后选择Shared Library(共享库),其他默认OK。

创建好后文件如下(我这里工程名为:dll)

其中dll.pro代码为:

1
2
3
4
5
6
7
8
9
10
11
12
TARGET = dll
TEMPLATE = lib
DEFINES += DLL_LIBRARY
SOURCES += \
    dll.cpp
HEADERS +=\
        dll_global.h \
    dll.h
unix {
    target.path = /usr/lib
    INSTALLS += target
}

dll_global.h代码为:

1
2
3
4
5
6
7
8
9
#ifndef DLL_GLOBAL_H
#define DLL_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(DLL_LIBRARY)
#  define DLLSHARED_EXPORT Q_DECL_EXPORT
#else
#  define DLLSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // DLL_GLOBAL_H

dll.h代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef DLL_H
#define DLL_H
#include <string>
#include "dll_global.h"
using namespace std;
class DLLSHARED_EXPORT Dll
{
public:
    Dll();
    ~Dll();
    void Print();
    string GetStrAdd(string str1, string str2);
};
extern "C"{
    DLLSHARED_EXPORT Dll* getDllObject(); //获取类Dll的对象
    DLLSHARED_EXPORT void releseDllObject(Dll*); //获取类Dll的对象
    DLLSHARED_EXPORT void helloWorld();
    DLLSHARED_EXPORT int add(int a,int b);
}
#endif // DLL_H

dll.cpp代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "dll.h"
#include <iostream>
Dll::Dll()
{
    std::cout<<"New Dll Object !"<<endl;
}
Dll::~Dll(){
    std::cout<<"Dll Object Des~~"<<endl;
}
void Dll::Print ()
{
    std::cout<<"Dll::Print !"<<endl;
}
string Dll::GetStrAdd (string str1, string str2)
{
    string s=str1+str2;
    std::cout<<"Dll::GetStrAdd->return->"<<s<<endl;
    return (s);
}
 
void helloWorld()
{
    std::cout << "GlobalFun->hello,world!"<<endl;
}
int add(int a,int b)
{
    std::cout<<"GlobalFun->add->return->"<<(a+b)<<endl;
    return a + b;
}
Dll* getDllObject()
{
    return new Dll();
}
void releseDllObject(Dll* dll){
    delete dll;
}

运行后在生成目录里生成了dll.dll、libdll.a、dll.o三个文件(Windows下使用MinGW编译运行),如图:

其中,.dll是在Windows下使用的,.o是在Linux/Unix下使用的。新建一个调用项目”DllTest“:

将dll.h和dll_global.h两个文件放到代码目录中:

其中DllTest.pro代码如下:

1
2
3
4
5
6
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = DllTest
TEMPLATE = app
SOURCES += main.cpp
LIBS +=dll.dll       #很重要!路径设置问题,如果错了就没有如果了~~~
LIBS +=”D:/API/dll.dll"   #~Right!

如果路径中有空格存在,一定要把整个路径放到一对双引号里!

这里网友评论里提出了更为规范的写法,更规范的写法如下:(非常感谢博友:多多多多多!!!)

1
2
3
4
5
6
7
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = DllTest
TEMPLATE = app
SOURCES += main.cpp
LIBS += -LD:/API -ldll       #中间不能有空格
#当使用相对路径时(相对与下面要说的)可使用:
#LIBS += -L. -ldll

main.cpp代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//#include <QtCore/QCoreApplication>
#include <iostream>
#include <QLibrary>
#include "dll.h"  //头文件还是需要加的,否则无法解析Dll类
typedef Dll* (*CreatDll)();//定义函数指针,获取类Dll对象;
typedef bool (*ReleseDll)(Dll*);
typedef void (*fun)();
int main( )
{
//    QCoreApplication a(argc, argv);
    QLibrary mylib("dll.dll");   //声明所用到的dll文件
    //判断是否正确加载
    if (mylib.load())
    {
            std::cout << "DLL  loaded!"<<std::endl;
            CreatDll creatDll = (CreatDll)mylib.resolve("getDllObject");
            ReleseDll decDll=(ReleseDll)mylib.resolve ("releseDllObject");
            fun hello=(fun)mylib.resolve ("helloWorld");
            if(hello)hello();
            if(creatDll&&decDll)
            {
                Dll *testDll = creatDll();
                testDll->GetStrAdd ("abc","ABD");
                testDll->Print ();
                decDll(testDll);
            }
    }
    //加载失败
    else
        std::cout << "DLL is not loaded!"<<std::endl;
//    return a.exec();
    mylib.unload ();
    return 0;
}
 
//输出为:
DLL  loaded!
GlobalFun->hello,world!
New Dll Object !
Dll::GetStrAdd->return->abcABD
Dll::Print !
Dll Object Des~~

这里将dll.dll文件放到调用项目的生成目录下(Debug上面一层)(这里对应上面的相对路径)即DllTest-Debug(我这里是这个名字,你那里可能不同)目录下:

编译,运行,OK!

这里要特别注意dll.dll的存放位置,还有要在.pro文件中增加一个 LIBS += dll.dll 用来指示路径,也可使用绝对路径如先将dll.dll放到D:/API/下,则应该设置为:LIBS += "D:/API/dll.dll"

如果想在资源管理器中直接双击exe文件打开,则dll.dll要放到和exe同目录下!

这个是显式调用的方法!

代码下载 http://download.csdn.net/detail/lomper/8183207

说明:下载的代码下载好后,要将LIBS += "D:/API/dll.dll" 更改成:LIBS += dll.dll 就可直接运行了。也可按规范写法:LIB += -LD:/API -ldll 或 LIBS+= -L.  -ldll (注意这里的“ . ”而且中间-L和路径之间不能有空格)建议代码下载后更改成相对路径的方式(项目DllTest.pro)

QT创建与调用Dll方法(包括类成员)--显式调用的更多相关文章

  1. QT 调用 DLL 方法(三种方法)

    Qt调用DLL方法一:使用Win32 API 在显式链接下,应用程序必须进行函数 调用以在运行时显式加载 DLL.为显式链接到 DLL,应用程序必须:? 调用 LoadLibrary(或相似的函 数) ...

  2. LoadRunner 调用dll方法

    本文主要介绍简单DLL的编写方法及在LoadRunner中局部调用与全局调用DLL方法. 1.动态链接库的编写 在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择W ...

  3. Java编译时根据调用该方法的类或对象所属的类决定

    class Base{     int x = 1;     static int y = 2; } class Subclass extends Base{     int x = 4;     i ...

  4. dll的加载方式主要分为两大类,显式和隐式链接

    之前简单写过如何创建lib和dll文件及简单的使用(http://blog.csdn.net/betabin/article/details/7239200).现在先再深入点写写dll的加载方式. d ...

  5. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  6. Java调用WebService方法总结(9,end)--Http方式调用WebService

    Http方式调用WebService,直接发送soap消息到服务端,然后自己解析服务端返回的结果,这种方式比较简单粗暴,也很好用:soap消息可以通过SoapUI来生成,也很方便.文中所使用到的软件版 ...

  7. go语言之进阶篇显式调用panic函数

    1.显式调用panic函数 示例: package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaa ...

  8. [转]如何在Java中调用DLL方法

    转载地址:http://developer.51cto.com/art/200906/129773.htm Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台 ...

  9. python调用dll方法

    在python中调用dll文件中的接口比较简单,实例代码如下: 如我们有一个test.dll文件,内部定义如下: extern "C"{ int __stdcall test( v ...

随机推荐

  1. windows server 2003和window2008区别

    windows 2003与windows 2008简介 windows 2003是微软老一代的服务器系统,自带iis 6,操作界面类似于windows XP,因为国内很多IDC都喜欢用盗版window ...

  2. k2安装LEDE

    固件下载时请用Breed Web 恢复控制台恢复固件,步骤如下:1.到LEDE官方网站下载最新开发版固件2.Web Breed台刷写固件3.将一台能上网的路由器LAN口接至K2 WAN口,等待K2连上 ...

  3. 5.监听器(Listener)

    1.监听器简介: 监听器主要用来监听对象的创建,属性的变化,是一个实现特定接口的普通Java类. Listener接口与事件对应表: 与 ServletContext 有关 ServletContex ...

  4. 锁、CAS操作和无锁队列的实现

    https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...

  5. 10-----BBS论坛

    BBS论坛(十) 10.1.客户端权限验证功能完成 (1)cms/cms_profile 显示当前用户的角色和权限 <tr> <td>角色:</td> <td ...

  6. 配置MapReduce程序运行环境

    已安装eclipse,hadoop 查看教程dblab.xmu.edu.cn/blog/hadoop-build-project-using-eclipse/

  7. shiro【filter】

    alt+7 OncePerRequestFilter public final void doFilter(ServletRequest request, ServletResponse respon ...

  8. Vue中的scoped和scoped穿透

    1.什么是scoped 在Vue文件中的style标签上有一个特殊的属性,scoped.当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染 ...

  9. SpringMVC什么时候配置 视图解析器

    当Action返回的是一个真实路径的时候,视图解析器可不进行配置 当Action返回的是逻辑路径的时候,我们必须要在配置文件中注册视图解析器并为该逻辑路径添加前缀和后缀

  10. 编译opencv python接口

    首先,安装依赖1 sudo apt-get install build-essential 2 sudo apt-get install cmake git libgtk2.0-dev pkg-con ...