动态库两种调用
来源:互联网 发布: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;}
看十,百遍,不如自己敲一遍,小小的动态库调用,也是有讲究的。
- 动态库两种调用
- 动态调用
- 动态链接库两种调用方式的比较
- 动态链接库两种调用方式的比较
- 动态链接库两种调用方式的比较
- oracle动态调用 动态调用存储过程
- 动态调用与静态调用
- 动态调用、静态调用dll
- 动态调用C++动态库
- 动态调用Web Service
- 动态调用Webservice
- 动态调用方法实例
- 如何动态调用WebService?
- VC动态调用DLL
- 如何动态调用WebService?
- 动态调用Webservice
- 动态调用Webservice
- 动态调用存储过程
- AppWidget实现机制分析--launcher添加和删除appwidget深入分析
- parallel与no_index
- 特征点检测学习_1(sift算法)
- PythonChallenge 挑战之路 Level-17
- 整理用Java实现数字转化成字符串左边自动补零方法
- 动态库两种调用
- v$session_longops视图
- Android开发者指南-摄像头-Camera
- oracle wm_concat(column)函数的使用
- vs2010 C#链接 ACCESS数据库
- AE中获取图层属性信息
- CIPAddressCtrl控件的用法:
- MFC创建属性表单
- CentOS 5.4 32位 OpenSSl OpenSSH升级过程.