• Windows DLL调用实例


          DLL全称Dynamic Link Library,是微软定义的动态链接库类型。动态链接库的好处不必多说。那么在windows下如何使用DLL呢?DLL的使用有2种方式:第一种称之为”显式链接”,只需提供DLL文件和知晓函数名即可;第二种称之为“隐式链接”,需要提供lib,头文件和dll,这种方式比较正规。首先,我们来制作一个dll文件。

          打开vs2010,选择Win32 Console Application,填入工程名”mydll”,在接下来的Application Settings设置的时候,将Application type设置为DLL,将Additional options设置为Empty project。

    分别创建mydllbase.h ,mydll.h和mydll.cpp文件。文件内容如下:

    mydllbase.h:

    #ifndef MYDLLBASE_H
    #define MYDLLBASE_H
    class mydllbase
    {
    public:
        virtual ~mydllbase(){};
        virtual int add(int a, int b) = 0;
    };
    #endif

    mydll.h:

    #ifndef MYDLL_H
    #define MYDLL_H
    class __declspec( dllexport ) mymath: public mydllbase
    {
    public:
        mymath(){}
        int add(int a, int b);
    };
    #endif

    mydll.cpp:

    #include "mydll.h"
    extern "C" __declspec(dllexport) mymath* getInstance()
    {
        return new mymath;
    }
    int mymath::add(int a, int b)
    {
        return a+b;
    }

    如何导出函数,classes,详见:

    http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

    http://msdn.microsoft.com/en-us/library/81h27t8c.aspx

    编译后生成:

    Mydll.dll  mydll.lib 文件。

    新建一个Console Application,创建main.cpp文件,将Mydll.dll mydll.lib mydll.h mydllbase.h拷贝到main.cpp同目录下。

    显式链接的方式调用dll:

    只要添加 mydllbase.h 头文件。

    main.cpp:

    #include <iostream>
    #include <cstdio>
    #include <Windows.h>
    #include "mydllbase.h"
    using namespace std;
    typedef mydllbase* (*getInstance)();
    
    int main()
    {
        getInstance func;
        int sum = 0;
        HINSTANCE hInstLibrary = LoadLibrary(L"mydll.dll");
        if (hInstLibrary == NULL)
        {
            cout<<"cannot load library"<<endl;
        }
        else
        {
            printf("load library successfully %p
    ", hInstLibrary);
        }
        func = (getInstance)GetProcAddress(hInstLibrary, "getInstance");
        if (func == NULL)
        {
            FreeLibrary(hInstLibrary);
            printf("GetProcAddress failed
    ");
        }
        else
        {
            printf("GetProcAddress load function successfully %p!
    ", func);
        }
        class mydllbase* m = func();
        if (m != NULL)
        {
            sum = m->add(1, 10);
            delete m;
        }
        cout<<"sum: "<<sum<<endl;
        FreeLibrary(hInstLibrary);
        return 0;
    }

    执行结果:

    显然,在显式链接中,我们不能直接调用class,需要通过一个全局getInstance函数,隐式地创建class的实例,同时需要创建一个基类,将所有成员函数命名成纯虚函数,然后让class继承基类函数,来达到捕获class实例的目的。这是多么麻烦啊!!!

    隐式链接的方式调用dll就简单多了:

    main.cpp:

    #include <iostream>
    #include <cstdio>
    #include "mydll.h"
    using namespace std;
    #pragma comment(lib, "mydll.lib")
    int main()
    {
        mymath m;
        cout<<"sum: "<<m.add(10, 1)<<endl;
    }

    执行结果:

    非常简单!通过#pragma comment()宏将lib引入lib库,可以像本地class一样调用dll的class。

  • 相关阅读:
    钩子函数和回调函数的区别
    观察者模式(Observer)和发布-订阅者模式(Publish/Subscribe)区别
    前端解决跨域问题的终极武器——Nginx反向代理
    CORS(cross-origin-resource-sharing)跨源资源共享
    Vue父子组件通讯
    js的变量——基本类型保存在栈中,引用类型保存在堆中
    python
    CentOS7 下 Zabbix3.4 源码安装
    linux配置ssh公钥认证,打通root用户的免密码输入的scp通道
    python
  • 原文地址:https://www.cnblogs.com/smallmaple/p/3676754.html
Copyright © 2020-2023  润新知