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