• QT创建与调用Dll方法(包括类成员)--显式调用


    看网上的好多关于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)

     

  • 相关阅读:
    nodejs微服务
    node 操作文件流 fs 同步与异步 流式文件的写入与读取
    node判断文件目录是否存在
    Nodejs 使用 Chrome DevTools 调试 --inspect-brk
    使用ovftool工具实现exsi上主机的导入导出
    redis哨兵
    LVS+Nginx
    nginx的proxy代理缓存
    flanneld启动报错Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
    flanneld启动报错Failed to create SubnetManager: parse first path segment in URL cannot contain colon
  • 原文地址:https://www.cnblogs.com/lomper/p/4112626.html
Copyright © 2020-2023  润新知