C++ 调用DLL的方法总结
文章分为以下几个部分:
1.DLL是什么?
2.为什么要加载DLL?
3.加载DLL的方法
4.什么时候用显式调用?什么时候用隐式调用?
5.lib文件是什么?
6.怎么通过显式调用加载DLL?
7.怎么通过隐式调用加载DLL?
8.总结
DLL是什么?
DLL又叫做动态链接库。DLL文件中存放的是各类程序的函数(子过程)实现过程,当程序需要调用函数时需要先载入DLL,然后取得函数的地址,最后进行调用。拿超级狗来说,他们提供的DLL文件里面所存放的内容就是超级狗的接口函数。
为什么要加载DLL?
如果想要使用超级狗API就必须加载超级狗提供的DLL。使用DLL文件的好处是程序不需要在运行之初加载所有代码,只有在程序需要某个函数的时候才从DLL中取出。另外,使用DLL文件还可以减小程序的体积。
加载DLL的方法
加载DLL有两种方法:(1)显式调用 (2)隐式调用
什么时候用显式调用?什么时候用隐式调用?
首先说一下,这两种方式都需要.h文件和DLL文件。隐式调用和显示调用最大的一个区别就是隐式调用还要用到lib文件。其次显示调用比较复杂,隐式调用比较简单。
如果说,只有.h文件和DLL文件,那么只可以通过显示调用的方式,如果有lib文件的情况下,一般都会选择比较简单的隐式调用,当然特殊情况下也可以选择显示调用的方法。
lib文件是什么?
上面刚提到,隐式调用还需要用到lib文件,那么问题来了,什么是lib文件?
lib有两种,一种是静态库,另一种就是隐式调用时配合DLL文件使用的,起链接的作用。
怎么通过显式调用加载DLL?
1. 显示调用必备两样东西:头文件、DLL文件
2. 将头文件和DLL文件放在项目目录下
3. LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)。GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用。FreeLibrary() 释放dll所占空间。
4. QT中通过QLibrary 类来加载DLL。
VS示例代码:
#include <windows.h> #include <stdio.h> void main(void) { typedef int(*pMax)(int a,int b); typedef int(*pMin)(int a,int b); HINSTANCE hDLL; PMax Max HDLL=LoadLibrary("MyDll.dll");//加载动态链接库MyDll.dll文件; Max=(pMax)GetProcAddress(hDLL,"Max"); A=Max(5,8); printf("比较的结果为%d\n",a); FreeLibrary(hDLL);//卸载MyDll.dll文件; }
怎么通过隐式调用加载DLL?
1. 隐式调用必备三样东西:头文件、DLL文件、lib文件
2. VS中将三者都放在项目目录下;QT中将头文件、lib文件放入项目目录下,将DLL文件放入输出目录下。
3. 添加lib文件。VS中右击项目à属性à链接器à附加依赖项à添加lib文件。QT中右击项目à添加库à选择库文件(lib文件)à完成,这样会自动在.pro文件中添加配置代码,也可以自己在.pro文件中添加代码,格式为:LIBS += -L位置 -l文件名。
4. 使用接口函数
VS示例代码(QT类似):
#include <iostream> #include "dog_api_cpp.h" #include "vendor_code.h" using namespace std; int main() { dog_status_t status; dog_handle_t handle; dog_size_t fsize; unsigned char membuffer[128]; //登录 status = dog_login(0, (dog_vendor_code_t *)vendor_code, &handle); cout << status<<endl; //获取文件大小 status = dog_get_size(handle, 1, /*文件ID*/ &fsize); cout << status << endl; cout << fsize << endl; //读取数据 status = dog_read(handle, 1, /* file ID */ 0, /* 字节偏移量 */ fsize, /* length */ &membuffer); /* file data */ cout << status << endl; cout << membuffer << endl; return 0; }
总结
这次学习超级狗API的使用,主要问题有如下几个:
1. 使用超级狗API到底该用哪个dll哪个lib?
2. 怎么加载dll和lib?
3. 函数该怎么调?
对于第一个问题,为什么会有这么一个问题?因为超级狗他们给了很多dll、lib,其中有64位的有32位的,有demo的有正式的,64位和32位主要是根据编译器来选择,VS和QT都是默认为32位的。Demo和正式的那我们肯定是要选择正式的。所以最终确定下来的应该是一个dll和一个lib。
对于第二个问题,怎么加载,在上面已经说得很清楚了。之所以花这么多篇幅介绍怎么加载dll就是因为,超级狗API的使用,最关键的地方就是dll的调用。
对于第三个问题,函数该怎么调用?首先要确定函数的返回类型,在超级狗API当中,所有的函数返回类型都是dog_status_t类型,这是返回的状态信息,是一个整数,不同的数字代表不同的状态,可以通过判断这个数字来确定下一步的操作。然后再通过对照API文档,理解要传递的参数是什么,哪几个参数是传递进去供函数使用的,哪个参数是函数执行完之后改变了的。
解决掉上述三个主要问题,超级狗API使用的问题也就解决了。
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}