借助工具可以获得Dll库函数的访问地址,以下推荐两款工具以供使用:
将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。
__declspec(dllexport) RETURN_TYPE FUNCTION()
由于在制作DLL导出函数时由于C++存在函数重载
__declspec(dllexport) FUNCTION(int,int)在DLL会被decorate,例如: 被decorate成为function_int_int,GetProcAddress取得FUNCTION地址时的不便extern "C"时,上述的decorate不会发生,因为C没有函数重载,如此一来被extern"C"修饰的函数,就不具备重载能力。extern "C" {
__declspec(dllexport) RETURN_TYPE FUNCTION(){
;
}
}
LoadLibrary、 GetProcAddress 和FreeLibrary注意DLL函数调用约定,必须一致
__stdcall Windows API默认的函数调用协议__cdecl C/C++默认的函数调用协议__fastcall 适用于对性能要求较高的场合假如我有一个函数接口如下:
//@ GETCOMCHECKSUM_API是一个宏定义
//@ #define GETCOMCHECKSUM_API __declspec(dllexport)
GETCOMCHECKSUM_API int fnGetComCheckSum(
const unsigned char* iCsArray, //[In]数组
const unsigned int iCsSize, //[In]数值
unsigned char& ioCsValue) //[In/Out]数值
那么我的调用应该这么写:
//@ __cdecl * 后面函数名可以自定义
typedef int(__cdecl *GetComCheckSum)(
unsigned char const *,
unsigned int,
unsigned char&);
function LoadLibrary(LibFileName : PChar): Thandle;如果函数操作成功,将返回装载 DLL 库模块的实例句柄,否则,将返回一个错误代码,错误代码的定义如下表所示
错误代码 含义
0 系统内存不够,可执行文件被破坏或调用非法
2 文件没有被发现
3 路径没有被发现
5 企图动态链接一个任务错误或者有一个共享或网络保护错误
6 库需要为每个任务建立分离的数据段
8 没有足够的内存启动应用程序
10 Windows 版本不正确
11 可执行文件非法或不是Windows 应用程序,或在. EXE映像中有错误
12 应用程序为一个不同的操作系统设计(如 OS/2)
13 应用程序为 MS DOS 4. 0 设计
14 可执行文件的类型不知道
15 试图装载一个实模式应用程序(为早期Windows 版本设计)
16 试图装载包含可写的多个数据段的可执行文件的第二个实例
19 试图装载一个压缩的可执行文件(文件必须被解压后才能被装载)
20 DLL 文件非法
21 应用程序需要 32 位扩展
//@ 定义句柄
HINSTANCE hSnKLib;
//@ 获取链接库句柄 Getchecksum为dll的文件名 即 Getchecksum.dll
//@ 系统将会在当前目录下寻找名为Getchecksum.dll的文件
//@ 至于为什么使用_T("") ,_T是一个宏,作用是让你的程序支持Unicode编码,Windows使用两种字符集ANSI和UNICODE
hSnKLib = LoadLibrary(_T("Getchecksum"))
//@ 如果未能成功获取,抛出错误
if (hSnKLib == NULL)
{
FreeLibrary(hSnKLib);
printf("LoadLibrary err\n");
getchar();
return 1;
}
function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;Module 包含被调用函数的 DLL 句柄,这个值由 LoadLibrary 返回,procName是指向含有函数名的以 nil 结尾的字符串指针,或者可以是函数的次序值.
函数名是一种更稳妥的选择。函数的入口地址,否则返回 nil 。//前面我们在头文件中声明了下述函数
typedef int(__cdecl *GetComCheckSum)(
unsigned char const *,
unsigned int,
unsigned char&);
//实例化并且获取函数地址
//fnGetComCheckSum为dll export出来的函数名,GetComCheckSum为我们引用时候声明的函数名
//这里做的工作就是将dll中函数与我们声明的联系到一块。
GetComCheckSum getcom = (GetComCheckSum)GetProcAddress(hSnKLib, "fnGetComCheckSum")
if (!getcom)
{
FreeLibrary(hSnKLib); //释放dll文件
//Add your code here
}
procedure FreeLibrary(Module: Thandle);FreeLibrary(hSnKLib);
问题描述:
问题定位:
解决方法两种:
修改GetProcAddress的第二个参数为真正的导出函数名称即可
在dll工程中添加DEF文件,写入如下内容:
EXPORTS
ExportFunc
