亲宝软件园·资讯

展开

VisualStudio动态链接库

CDamogu 人气:0

工具集

借助工具可以获得Dll库函数的访问地址,以下推荐两款工具以供使用:

Dependency Walker官网

Depends22_x64.zip

Dllexp-x64.zip

如何生成

__declspec(dllexport)

将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。

__declspec(dllexport) RETURN_TYPE FUNCTION()

extern “C”

由于在制作DLL导出函数时由于C++存在函数重载

extern "C" {
  __declspec(dllexport) RETURN_TYPE FUNCTION(){
    ;
  }
}

如何使用

声明调用

注意DLL函数调用约定,必须一致

Example

假如我有一个函数接口如下:

//@ 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&);

LoadLibrary

如果 LibFileName 没有包含一个路径,系统将按照:当前目录、Windows 目录、Windows 系统目录、包含当前任务可执行文件的目录、列在 PATH 环境变量中的目录等顺序查找文件。

如果函数操作成功,将返回装载 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  位扩展

Example

//@ 定义句柄
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;
}

GetProcAddress

大多数情况下,用函数名是一种更稳妥的选择。

如果该函数执行成功,则返回 DLL 中由参数 ProcName 指定的过程或函数的入口地址,否则返回 nil 。

Example

//前面我们在头文件中声明了下述函数
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
}

FreeLibrary

Example

FreeLibrary(hSnKLib);

FAQS

Question 1: GetLastError获取错误代码127

问题描述:

问题定位:

解决方法两种:

EXPORTS
               ExportFunc

在这里插入图片描述

参考案例

GetProcAddress 使用注意事项

加载全部内容

相关教程
猜你喜欢
用户评论