dll(dynamic link library)动态链接库相当于是把一些函数或者类啊编译成源码.不过它不可执行.只是当被其他exe或dll调用到时才被加载到内存中.像windows那些API都是放到一些dll文件中.比如kernel32.dll,它包含管理内存,进程,线程的一些函数.User32.dll包含用于执行用户界面任务的函数.
而当我们写代码要用到dll中的函数时,在编译阶段一般只要个lib文件,里面有dll中的函数和类的描述信息,但没有实现代码信息.
下面来看一个创建dll的简单示例
创建 Win32 Project-->application type选DLL.
project名字就取DllTest.创建好项目后我们会看到自动生成了.dllmain.cpp和DllTest.cpp,前一个文件不用去动它.
我们就在DllTest.cpp文件中添加如下内容
_declspec(dllexport)
int multiply(int one , int two) //返回两数相乘的积
{
return one*two;
}
编译下这个项目.你会在目录下面看到DllTest.dll 和 DllTest.lib 这两文件.等会其他项目中要用它俩.
新建一个简单的Win32 console application 项目.把上面的DllTest.dll和DllTest.lib两文件拷到项目目录下.再添加如下代码
#include <iostream>
using namespace std;
#pragma comment(lib, "./DllTest.lib")
int multiply( int one , int two) ; //函数声明,函数定义最终是去调用DllTest.dll中的代码了.
//另外最好是写成这样_declspec(dllimport) int multiply( int one , int two)
int main()
{
int ret = multiply( 4,5);
cout<<ret; //20
return 0;
}
当然了,如果你嫌#pragma comment(lib, "./DllTest.lib")这样写麻烦,也不不写,而是在项目的property page -->Linker -->Input -->Additional Dependencies里面敲入DllTest.lib
上面是比较简单的再来看个复杂点的.
跟前面一样还是一样先创建一个win32 dll项目名为DllTest.然后添加class Arwen.
/////Arwen.h中内容/////////////////
#pragma once
#include <iostream>
#define DLL_API _declspec(dllimport)
class DLL_API Arwen{
public:
int age;
void Fun();
};
//////////Arwen.cpp中内容/////////////////
#include "StdAfx.h"
#include "Arwen.h"
#define DLL_API _declspec(dllexport)
void Arwen::Fun()
{
std::cout<<"my age is "<<age;
}
使用DLL
新建一个win32 console application ,把DllTest.dll和Dll.lib拷贝过去.另外把头文件Arwen.h也拷过去.
#include "Arwen.h"
#pragma comment(lib, "./DllTest.lib")
int main()
{
Arwen an;
an.age = 25;
an.Fun();
return 0;
}
前面讲的是静态加载DLL,现在瞧下怎么动态加载.
#include <windows.h>
typedef int( *pFun) (int a, int b); //定义一个函数指针类型
void main()
{
HINSTANCE hInt = LoalLibrary( _T( "../debug/DllTest.dll") ); //动态加载
pFun mulitplyFun = (pFun) GetProcAddress( hInt , (LPCSTR) MAKEINTRESOURCE(2)); //函数序列号是通过工具dumpbin查到的
}
工具dumpbin的使用.
1.先找到vsvar32.bat文件,目录是在: 安装目录\VC\bin\vcvars32.bat.然后在cmd里面执行它
2.先切换到dll文件所在目录,假如这里是DllTest.dll,然后执行命令dumpbin - exports DllTest.dll
3.得到所以导出函数信息,其中ordianl那一列指函数序列号 , name那一列则是编译之后函数的名字,比之前的函数名多了些前缀后缀.