动态库两种调用

来源:互联网 发布:Coldplay主唱知乎 编辑:程序博客网 时间:2024/05/29 14:24

看过关于动态库的调用例子,于是决定动手做一做:
dll的对外接口声明头文件,Mydll.h:

//Mydll.h#include <stdio.h>#include <stdlib.h>#include "Public.h"#define  DLL_EXPORT/*extern "c"*/ __declspec(dllexport)//导出#define  CUST_API_stdcall//标准调用DLL_EXPORT void CUST_API DisplayVersion(TCHAR *Info);//显示版本DLL_EXPORT int CUST_API Calc(int ia,int ib);//DLL_EXPORT int CUST_API MetiCalc(int ia,int ib);//新增加接口//mydll.cpp#include "MyDll.h"void CUST_API DisplayVersion(TCHAR *Info){wcscpy_s(Info,sizeof(VERSION),VERSION);//#define VERSION  ver 1.0return;}int CUST_API Calc(int ia,int ib){return ia+ib;}int CUST_API MetiCalc(int ia,int ib){return ia*ib;}

编译后,生成DllTest.lib 和 DllTest.dll
第一种方法:静态调用
理解:lib描述dll信息和函数入口地址,在编译时期加载到可执行程序中的。
若dll增加新API接口,新接口在使用时,必须要同时更新lib 才能使用,否则会找不到新接口函数的地址,由此可见,lib包含了描述dll 的接口描述信息。
//dlltest.h#include <iostream>#include <Windows.h>using namespace std;#pragma comment(lib,"..\\ApDll\\DllTest.lib")//加载lib库#define  DLL_EXPORT/*extern "c"*/ __declspec(dllexport)//导出#define  CUST_API_stdcall//标准调用DLL_EXPORT void CUST_API DisplayVersion(TCHAR *Info);//dll中显示版本函数DLL_EXPORT int CUST_API Calc(int ia,int ib);DLL_EXPORT int CUST_API MetiCalc(int ia,int ib);int _tmain(int argc, _TCHAR* argv[]){TCHAR Version[50] = {0};int  a = 10,b=12;DisplayVersion(Version);wcout<<Version<<endl;wcout<<Calc(a,b)<<endl;}Result: ver 1.0          120

第二种方法:动态加载
首先,要定义指向动态库中所对外提供的函数类型,的函数指针。
函数指针定义的理解:
typedef void(_stdcall *FunName)(paramtypes 1,paramtypes 2);//定义指向调用类型为_stdcall,参数个数,类型如paramtypes1,paramtypes 2,返回值为void类型的函数指针
这里注意,定义函数指针时,返回值 (*pName)(参数),3个部分;
然后,LoadLibrary(Path); Path为dll所在路径,可以是system目录,也可以其他指定目录。加载成功之后会返回一个Hmodel模块句柄。
再利用这个模块句柄去,获取相应函数的地址。
函数指针调用时,不同于普通的指针,它不需要间接寻址,“*”;
用完dll之后要记得ReleaseLibrary() ;
#include <iostream>#include <Windows.h>using namespace std;typedef void (CUST_API *DisVer)(TCHAR *Info);typedef int  (CUST_API *CalcOprt)(int ia,int ib);int _tmain(int argc, _TCHAR* argv[]){TCHAR Version[50] = {0};int  a = 10,b=12;HMODULE hmodle = LoadLibrary(_T("..\\ApDll\\DllTest.dll"));//动态加载dllif(NULL == hmodle){wcout<<"load dll failed!"<<endl;return -1;}DisVer displayVer = (DisVer)::GetProcAddress(hmodle,"DisplayVersion");//根据模块地址,按找函数名,获取函数地址DisplayVersion(Version);try{if (NULL == displayVer){wcout<<_T("Load  function error!")<<endl;}(displayVer)(Version);//用函数指针调用函数wcout<<Version<<endl;}catch (...){;}system("pause");return 0;}

看十,百遍,不如自己敲一遍,小小的动态库调用,也是有讲究的。


原创粉丝点击