C语言调用C语言写的动态链接库DLL(方式二:windowAPI动态加载DLL法)


无参数的函数:

新建一个空项目,直接写入下面代码

#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;
}