接
前篇文章,通过一个简单的例子讲解dll的动态加载
在Visual Stadio 2008 Command Prompt输入命令:
新建名称为testdll的工程,下一步时注意应用类型选为dll,添加文件addfunc.h和addfunc.cpp
addfunc.h 声明两个加法函数
// addfunc.h
#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif
TESTDLL_API int add(int x, int y);
TESTDLL_API int add(int *arr, int len);
addfunc.cpp 加法函数的实现
#include <stdio.h>
#include "addfunc.h"
TESTDLL_API int add(int x, int y)
{
return x+y;
}
TESTDLL_API int add(int *arr, int len)
{
int i = 0;
int sum = 0;
for (i = 0; i < len; i++)
sum += arr[i];
return sum;
}
编译就可以生成testdll.dll
在Visual Stadio 2008 Command Prompt输入命令:
dumpbin -exports testdll.dll
可以看到dll文件导出的函数名和偏移地址:
1 0 0001107D ?add@@YAHHH@Z = @ILT+120(?add@@YAHHH@Z)
2 1 00011122 ?add@@YAHPAHH@Z = @ILT+285(?add@@YAHPAHH@Z)
测试dll的导出函数:
#include <stdio.h>
#include <windows.h>
typedef int(*ADDFUNC)(int,int);
typedef int(*ADDFUNC2)(int*,int);
int main()
{
int x = 7;
int y = 13;
HINSTANCE hInstLibrary = LoadLibrary("testdll.dll");
ADDFUNC add = (ADDFUNC)GetProcAddress(hInstLibrary,"?add@@YAHHH@Z");
printf("the sum is %d\n",add(x,y));
ADDFUNC2 add2 = (ADDFUNC)GetProcAddress(hInstLibrary,"?add@@YAHPAHH@Z");
int a[5]={1,2,3,4,5};
printf("the sum is %d\n",add2(a,5));
FreeLibrary(hInstLibrary);
system("pause");
return 0;
}
这样加载函数函数名很复杂,那么可在testdll工程中添加.def文件,指定导出名称
testdll.def
LIBRARY "testdll"
EXPORTS
add1=?add@@YAHHH@Z
add2=?add@@YAHPAHH@Z
再次查看导出函数名
1 0 0001107D ?add@@YAHHH@Z = @ILT+120(?add@@YAHHH@Z)
2 1 00011122 ?add@@YAHPAHH@Z = @ILT+285(?add@@YAHPAHH@Z)
3 2 0001107D add1 = @ILT+120(?add@@YAHHH@Z)
4 3 00011122 add2 = @ILT+285(?add@@YAHPAHH@Z)
多了add1,add2,通过GetProcAddress加载函数时可以直接用这两个名称
上面的加法函数重载了,函数名相同但参数不同。
如果没有重载函数,那么.def文件可以简单定义如下:(Microsoft链接器解析这个def文件时,只会导出这个文件指定的函数名)
EXPORTS
MyFunc1
MyFunc2