• QT编写DLL并调用详解


    创建DLL源文件

     创建好后如图:

    编写函数

    DLL在QT中可以静态调用也可以动态调用,如果只采用静态调用的方法,那DLL的函数编写和普通程序没有什么差别。如果要使用动态调用的方法,那么函数必须是C函数!

    C没有“类”的概念,因此像void sky::test() 这样的写法是错误的!

    C函数的编写:

    1、在.h头文件中:

    1. //导出宏
    2. #ifdef Q_OS_WIN
    3. #define MY_EXPORT __declspec(dllexport) //Windows系统需要这个参数
    4. #else
    5. #define MY_EXPORT
    6. #endif
    7. //定义一个C函数
    8. extern "C" MY_EXPORT int Cfun(int i); //导出函数必须使用 extern "C" MY_EXPORT 做前缀

    注意:如上面代码所示, C导出函数必须使用:extern "C" MY_EXPORT  做为前缀

    2、.cpp文件:

    1. //这里也必须使用 extern "C" MY_EXPORT 作为前缀
    2. extern "C" MY_EXPORT int Cfun(int i){
    3. return i;
    4. }

    这样,一个简单的C函数就写好了,编译即可产生dll文件

    需要注意的是:如果要让DLL文件在其它编程工具中调用, 变量类型不要使用QT专有类型,比如QString

    题外话,QString的处理速度比string要慢60%-70%

    QT调用DLL的方法

    一、静态调用

    1、将dll源码目录中的两个.h文件拷贝到程序源码目录下,如图:

    2、在.h头文件中include,如图:

    3、拷贝DLL文件

    如果DLL采用MSVC编译,将生成的.dll和.lib文件拷贝到程序目录下,如图: 

    当然,为了源码目录整洁,可以创建目录将它们放在下级目录中。

    如果DLL文件是MinGW编译,只需拷贝DLL文件。

    4、在.pro文件末尾添加一行:

    LIBS += -L$$PWD -lskyLib

    其中,-L表示指定库路径,$$PWD表示.pro文件所在路径,-l加载库文件。

    如果程序使用MSVC编译器,还可以使用其专属方法,在.h头文件中添加:

    #pragma comment(lib,"Z:\\test\\skyLib") //MSVC编译器专属方法,不推荐使用

    并不推荐使用这种专属方法来加载DLL,如果使用了,那么还要将.dll和.lib文件拷贝到编译输出目录中,如图:

    否则调试不了,会报程序异常结束,如图:

    设置成功后,就可以使用DLL中的函数了。

    5、使用DLL中的函数

    C函数可以直接使用,如图:

     普通函数,则需要创建类实例,如图:

     二、动态调用

    动态调用无须在.pro文件中设置LIBS也不需要导入dll的头文件,但DLL的导出函数必须是C函数!C函数的编写方法如果忘了,可以翻上去再看一下

    先来看一下C函数和普通函数的区别:

    上图Cfun是C函数,其它是普通函数。普通函数名称像这样,是无法调用的!

    动态调用方法:

    1、在.h头文件中添加代码:

    1. #include "QLibrary"
    2. typedef int (*newCfun)(int i);
    3. newCfun funtest; //用于存放DLL函数的指针

    typedef这句代码中,第一个int是函数类型,要和导出函数中的类型一致,(*newCfun) 这个名称自取,和导出函数无关。(int i)对应导出函数中的参数,类型、数量需要一致。

    2、.cpp文件中,写入代码:

    1. QLibrary *lib = new QLibrary("Z:/mingw/skyLib.dll"); //加载DLL文件
    2. if(lib->load()){
    3. qDebug() <<"DLL加载成功";
    4. funtest = (newCfun)lib->resolve("Cfun");//这里的两个newCfun 就是前面typedef定义的那个。而Cfun则是要调用的导出函数的名称,不能错!
    5. if (funtest){
    6. qDebug()<<"解析成功";
    7. //解析成功后,就可以使用funtest()来调用Cfun函数了:
    8. qDebug()<<funtest(123);
    9. }
    10. }

    我把它写在了构造函数里,根据情况也可以写在其它地方

  • 相关阅读:
    数分-工具-Pandas2-pandas基础
    2023 年前端 UI 组件库概述,百花齐放!
    【Android】 Glide 官方库自带的图片裁切类
    Python应用开发——串口通信
    NumPy基础知识
    parsel的使用
    linux中的lo介绍及作用(回环接口 回环IP)
    Golang http 请求如何设置代理
    1092:求出e的值
    css3选择器用法合集
  • 原文地址:https://blog.csdn.net/s806903/article/details/126914925