目录
工具集如何生成__declspec(dllexport)extern “C”如何使用声明调用ExampleLoadLibraryExampleGetProcAddressExampleFreeLibraryExampleFAQSQuestion 1: GetLastError获取错误代码127参考案例工具集
借助工具可以获得Dll库函数的访问地址,以下推荐两款工具以供使用:
Dependency Walker官网
(资料图)
Depends22_x64.zip
Dllexp-x64.zip
如何生成
__declspec(dllexport)
将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。
__declspec(dllexport) RETURN_TYPE FUNCTION()
extern “C”
由于在制作DLL导出函数时由于C++存在函数重载
因此__declspec(dllexport) FUNCTION(int,int)
在DLL会被decorate,例如: 被decorate成为function_int_int,而且不同的编译器decorate的方法不同,造成了在用GetProcAddress
取得FUNCTION地址
时的不便使用extern "C"
时,上述的decorate不会发生,因为C没有函数重载,如此一来被extern"C"修饰的函数,就不具备重载能力
。
extern "C" { __declspec(dllexport) RETURN_TYPE FUNCTION(){ ; } }
如何使用
动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入口地址。当一个 DLL 文件用 LoadLibrary 显式加载后,在任何时刻均可以通过调用 FreeLibrary 函数显式地从内存中把它给卸载。动态调用使用的 Windows API 函数主要有 3 个, 分别是LoadLibrary
、 GetProcAddress
和FreeLibrary
声明调用
注意DLL函数调用约定,必须一致
__stdcall
Windows API默认的函数调用协议__cdecl
C/C++默认的函数调用协议__fastcall
适用于对性能要求较高的场合
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
[格式]function LoadLibrary(LibFileName : PChar): Thandle
;[功能] 加载由参数 LibFileName 指定的 DLL 文件[说明] 参数 LibFileName 指定了要装载的 DLL 文件名
如果 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
格式:function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;
功能: 返回参数 Module 指定的模块中,由参数 ProcName 指定的过程或函数的入口地址说明: 参数 Module
包含被调用函数的 DLL 句柄,这个值由 LoadLibrary 返回,procName
是指向含有函数名的以 nil 结尾的字符串指针,或者可以是函数的次序值.
大多数情况下,用函数名
是一种更稳妥的选择。
如果该函数执行成功,则返回 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
格式:procedure FreeLibrary(Module: Thandle);
说明:将由参数 Module 指定的 DLL 文件从内存中卸载 1 次。说明:Module 为 DLL 库的句柄。这个值由 LoadLibrary 返回。由于 DLL 在内存中只装载一次,因此调用 FreeLibrary 首先使 DLL 的引用计数减 1,如果计数减为 0 则卸载该 DLL注意:每调用一次 LoadLibrary 函数就应调用一次 FreeLibrary 函数,以保证不会有多余的库模块在应用程序结束后仍留在内存中,否则导致内存泄漏。
Example
FreeLibrary(hSnKLib);
FAQS
Question 1: GetLastError获取错误代码127
问题描述:
采用"运行期间动态链接"自己的dll文件LoadLibrary成功获取dll模块句柄但是GetProcAddress(hModule, “ExportFunc”)却返回NULL,GetLastError获取错误代码127,意思是“找不到指定程序”问题定位:
用Depends工具(VS2010默认没有,需另行下载:http://www.dependencywalker.com/),查看dll的导出函数名称。发现导出函数名不再是“ExportFunc”,而根据函数的返回类型和参数进行了“decorate”,变为了“?ExportFunc@@YAXPB_W@Z”。解决方法两种:
修改GetProcAddress的第二个参数为真正的导出函数名称即可在dll工程中添加DEF文件,写入如下内容:EXPORTS ExportFunc重新编译dll工程。再次用Depends工具查看导出函数名称,即为“ExportFunc”。工程–链接器–输入 的模块定义文件中,将自己的DEF文件加上
参考案例
GetProcAddress 使用注意事项
到此这篇关于VisualStudio制作DynamicLinkLibrary动态链接库文件的文章就介绍到这了,更多相关VisualStudio动态链接库文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 2充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 3好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 4名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 5亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 6京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 7网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 8市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 9北京市市场监管局为企业纾困减负保护经济韧性
- 10市场监管总局发布限制商品过度包装标准和第1号修改单