新建一个空项目,直接写入下面代码
#include <stdio.h> #include <Windows.h> /* 使用windowAPI动态加载dll只需要一个dll文件即可,不需要lib文件,也不需要头文件 涉及到的API函数: LoadLibrary() 加载dll 注意:如果使用unicode编码,字符串前要加L,使用多字节编码不需要加L,如果错了 就会加载失败 FreeLibrary() 释放dll 与LoadLibrary()成对使用 GetProcAddress() 获取函数指针 GetModuleHandle 可以用来检测当前进程中是否加载了某库 GetModuleFileName //获取某库的全路径 */ int main(){ //加载dll HMODULE hModule = GetModuleHandle("D:/VS项目/hello/Debug/hello.dll");//判断是否已加载 if (hModule == NULL){ hModule = LoadLibrary("D:/VS项目/hello/Debug/hello.dll"); //加载dll } if (hModule == NULL){//检测是否加载成功 printf("加载dll失败!\n"); getchar(); return 0; } FARPROC fn = GetProcAddress(hModule, "SayHello");//获取 SayHello这个函数的指针 fn(); //执行这个函数 /*获取这个库的全路径*/ char path[255] = { 0 }; GetModuleFileName(hModule, path,255); printf("%s\n", path); //释放dll FreeLibrary(hModule); getchar(); return 0; }
以上调用方式只能调用没有参数的函数.那么带参数的该怎么办呢?
先简化一下代码,并把函数 换成一个带参数的试一下
#include <stdio.h> #include <Windows.h> int main(){ HMODULE hModule = LoadLibrary("D:/VS项目/hello/Debug/hello.dll"); //加载dll FARPROC fn = GetProcAddress(hModule, "SayHello");//获取 SayHello这个函数的指针 /*获取带参数的函数地址试一下*/ FARPROC myfunAdd = GetProcAddress(hModule, "myfunAdd");//获取 SayHello这个函数的指针 int x = myfunAdd(5,6); //执行这个带参数的函数 /*此时 编译是可以通过,但是执行会出现错误*/ FreeLibrary(hModule);//释放dll getchar(); return 0; }
为什么带参数就不行呢?
我们在FARPROC上查看定义
typedef int (FAR WINAPI *FARPROC)();
原来FARPROC只是一个无参数的函数指针类型
那么我们只需要重新定义一个带参数的函数指针类型即可,复制他的定义方法稍微修改一下
typedef int (*MyfunAdd)(int a,int b);
然后在返回值的类型换成我们自己定义的带参数的函数指针类型,并加上强制类型转换
MyfunAdd myfunAdd = (MyfunAdd)GetProcAddress(hModule, "myfunAdd");
然后再调用就没有问题了,完整代码如下:
#include <stdio.h> #include <Windows.h> typedef int (*MyfunAdd)(int a,int b); int main(){ HMODULE hModule = LoadLibrary("D:/VS项目/hello/Debug/hello.dll"); //加载dll FARPROC fn = GetProcAddress(hModule, "SayHello");//获取 SayHello这个函数的指针 MyfunAdd myfunAdd = (MyfunAdd)GetProcAddress(hModule, "myfunAdd");// int x = myfunAdd(5,6); //执行这个带参数的函数 printf("%d\n", x); FreeLibrary(hModule);//释放dll getchar(); return 0; }