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\n", hInstLibrary);
    }
    func = (getInstance)GetProcAddress(hInstLibrary, "getInstance");
    if (func == NULL)
    {
        FreeLibrary(hInstLibrary);
        printf("GetProcAddress failed\n");
    }
    else
    {
        printf("GetProcAddress load function successfully %p!\n", 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。

posted @ 2014-04-20 17:53  smallmaple  阅读(5542)  评论(0编辑  收藏  举报