动态库两种调用

看过关于动态库的调用例子,于是决定动手做一做:
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.0
	return;
}

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"));	//动态加载dll
	if(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;
}

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


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值