编写常规DLL

//mathlib.h
#ifndef _MYMATH_H
#define _MYMATH_H

extern "C" int  _declspec(dllexport) Summary(int n);
extern "C" int  _declspec(dllexport) Factorial(int n);

#endif

//mathlib.cpp
#include "stdafx.h"
#include "mathlib.h"

int Summary(int n)
{
	int sum=0;
	int i;
	for(i=1;i<=n;i++)
	{
		sum+=i;
	}
	return sum;
}

int Factorial(int n)
{
	int Fact=1;
	int i;
	for(i=1;i<=n;i++)
	{
		Fact=Fact*i;
	}
	return Fact;
}

以上编译成常规DLL,用于下面:

// dllcall1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
typedef int (*lpFun)(int);//定义函数指针类型


int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hDll;//DLL句柄
	lpFun SumFun,FactorialFun;//函数指针
	hDll=LoadLibrary(_T("dllCall.dll"));//载入指定的动态链接库
	if(hDll != NULL)
	{
		SumFun = (lpFun)GetProcAddress(hDll,"Summary");//GetProcAddress()函数返回类型为FARPROC,强制转换成lpFun
		if(SumFun!=NULL)
		{
			int result=SumFun(10);
			std::cout<<"Sum(10)="<<result<<std::endl;
		}
		FactorialFun=(lpFun)GetProcAddress(hDll,"Factorial");
		if(FactorialFun!=NULL)
		{
			int result=FactorialFun(10);
			std::cout<<"10!="<<result<<std::endl;
		}
		FreeLibrary(hDll);//释放指定的动态链接库
	}
	return 0;
}


编写常规DLL_第1张图片

常规DLL的优点有以下几方面:

客户程序不必是一个MFC应用程序。它只需要能调用C函数即可,既可以是MFC应用程序,也可以是Delphi或Visual Basic应用程序。

在常规DLL的内部可以使用C++类,然后只导出C函数的包装器。这样,对内部的C++类的任何修改都不会影响到调用它的应用程序或DLL。

在主函数中定义了一个DLL HINSTANCE句柄实例hDll,通过Win32 API函数LoadLibrary动态加载了DLL模块。在主函数中通过Win32 API函数GetProcAddress()得到了所加载DLL模块中函数的地址,并使用函数指针变量保存。这样就可以使用函数指针调用DLL中导出的函数。最后,在应用项目中使用完DLL后,应立即调用FreeLibrary()函数释放已经加载的DLL模块。

在加载DLL时,Windows必须找到实际的物理文件。Windows在加载DLL时按以下顺序寻找文件。

1-当前应用程序的可执行模块所在的目录

2-当前目录

3-Windows系统目录

4-Windows目录

5-PATH环境变量中列出的目录

你可能感兴趣的:(编写常规DLL)