DLL学习之 非MFC动态库入门开发导出函数篇

  非MFC动态库也就是WIN32的DLL,它不使用MFC类库,其导出的函数是标准的C接口,能被非MFC和MFC的应用程序调用.所以非MFC动态库应用广泛.

  1.导出函数&链接方式

  1.1.概述

  DLL中的函数可以分为两种:导出函数和DLL内的函数,其中DLL内的函数只能在DLL程序中使用,而不能被外部程序使用,而导出函数可以被应用程序调用.

  在DLL中导出函数声明有两种方式:

  (1)在定义函数时使用_declspec(dllexport)关键字;

  (2)创建模块定义文件(.def),把导出函数名加入模块定义文件中.

 

  链接方式包括显式链接和隐式链接.

  1.2.实例

  下面介绍一个WIN32DLL导出函数实例.

  首先建立一个空项目,如下图所示.

  新建一个头文件"Calculation.h",使用第一种声明方式.内容如下:

  

extern "C" float _declspec(dllexport)calculate(float x,float y,int type);//声明导出函数

  再新建一个CPP文件"Calculation.cpp",内容如下:

 

#include "Calculation.h"//根据type的值决定进行四则运算
float calculate(float x,float y,int type)
{
    switch(type)
    {
    case 0:
        {return (x+y);}
    case 1:
        {return (x-y);}
    case 2:
        {return (x*y);}
    case 3:
        {return (x/y);}
    }
}

  编译之后,你可以在DUBUG文件夹下找到.lib和.dll文件.这就是我们所需要的.

  利用VS中的depends工具打开我们刚才编写的DLL文件,我们可以看到如下所示.很明显,我们可以看到DLL中有calculation函数.

  

  有了上述两个文件之后,我们需要建立一个应用程序来对其进行调用.把DLL的里边的函数进行导出,然后在应用程序中使用该导出函数.

  首先是显示链接.(请一定要确保.DLL和.LIB文件在对应的文件夹下面再进行加载DLL操作!)

//显式调用DLL
#include <iostream>
#include <stdio.h>
#include "Windows.h"//使用HINSTANCE类型和LoadLibrary,GetProcAddress,FreeLibrary等API函数

using namespace std;

typedef float (* TheCalculate)(float,float,int);//宏定义calculate函数指针类型

void main()
{
    HINSTANCE hdll;//DLL的句柄
    TheCalculate calfunc;//函数指针
    hdll=LoadLibrary("..\\Debug\\Win32DLL.dll");//LoadLibrary函数加载DLL,!要注意DLL的存放路径!
    if(hdll!=NULL)
    {
        calfunc=(TheCalculate)GetProcAddress(hdll,"calculate");//通过该函数获得导出函数的地址
    }
    float x,y;
    int type;
    printf("本程序用于测试开发的Win32DLL.dll\n");
    cout<<"请输入用于计算的X值:";
    cin>>x;
    cout<<"请输入用于计算的Y值:";
    cin>>y;
    cout<<"请输入运算类型:(0:加法;1:减法;2:乘法;3:除法)\n";
    cin>>type;
    float result=calfunc(x,y,type);//调用DLL函数进行计算
    FreeLibrary(hdll);//释放DLL
    cout<<"运算结果为:"<<result<<endl;
    system("pause");
}


运行结果如下所示:

  当然,DLL导出函数的方式第二种同样有效.把之前Calculate.h文件中的声明中的关键字_declspec(dllexport)去掉.同时新建TextFile,并且命名为"Win32DLL.def",并且添加如下代码:

;Win32DLL.def:导出DLL函数
LIBRARY "Win32DLL"
DESCRIPTION "实现一个Win32DLL"
EXPORTS
    calculate @1

  第一行";"后面的是注释.
  而Calculate.h中的内容如下所示:

  

extern "C" float calculate(float x,float y,int type);//声明导出函数

  编译之后将生成的.DLL文件拷贝到原应用程序的DEBUG文件夹下,再运行应用程序对其进行调用.可得出与第一种声明方法一样的结果.在此不重复.

  相继讨论了两种导出函数声明和显示链接之后,最后再进行隐式链接的讨论.

  

#include <iostream>
#include <stdio.h>
#pragma comment(lib,"Win32DLL.lib");//注意此处是.lib文件,而不是.dll文件,但同时应把.dll文件加到当前文件夹下
extern "C" _declspec(dllimport)float calculate(float x,float y,int type);

using namespace std;

void main()
{
    float x,y;
    int type;
    printf("本程序采用隐式链接的方式测试开发的Win32DLL.dll\n");
    cout<<"请输入用于计算的X值:";
    cin>>x;
    cout<<"请输入用于计算的Y值:";
    cin>>y;
    cout<<"请输入运算类型:(0:加法;1:减法;2:乘法;3:除法)\n";
    cin>>type;
    float result=calculate(x,y,type);
    cout<<"运算结果为:"<<result<<endl;
    system("pause");
}

  对于隐式链接.lib和.dll文件都应该被添加到当前应用程序的文件夹下.而显示链接则只需要一个.dll文件被添加到适当位置即可.

  该隐式链接的程序运行结果如下所示:

 

  暂时写到这.下一篇将会是导出变量.

  2012-04-29

  23:39:38

posted @ 2012-04-29 23:40  jianglirui  阅读(473)  评论(0编辑  收藏  举报