使用Visual Studio来创建动态库/静态库,并加载

使用Visual Studio来创建动态库

第一步新建一个控制台程序

使用Visual Studio来创建动态库/静态库,并加载_第1张图片

第二步去掉SDL安全开发周期,以及选中创建DLL空项目

使用Visual Studio来创建动态库/静态库,并加载_第2张图片

在资源管理器中添加.h.cpp文件

使用Visual Studio来创建动态库/静态库,并加载_第3张图片

使用Visual Studio来创建动态库/静态库,并加载_第4张图片

.h文件里可以写上函数的声明:

#pragma once //编译器命令 once头文件卫士

extern "C"/*以C的方式编译这段函数*/ __declspec(dllexport)/*将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。

*/ int Add(int a,int b); 

.cpp文件

#include "testdllh.h"
int Add(int &a, int &b)
{
	return a + b;
}

这里不能直接编译,因为直接编译会生成dll,dll是无法直接运行的,所以这里我们选择生成:

使用Visual Studio来创建动态库/静态库,并加载_第5张图片


上面表示生成成功,我们这里来调用dll试试:

使用Visual Studio来创建动态库/静态库,并加载_第6张图片

代码如下:

#include "testdllh.h"
#include 
#include 
int main(){
	HINSTANCE h = LoadLibraryA("ConsoleApplication10.dll");	//加载动态库
	typedef int(*FunPtr)(int a, int b);//定义函数指针来指向Dll动态库里的函数  
	if (h == NULL)
	{
		FreeLibrary(h);
		printf("load dll error\n");
	}
	else{
		FunPtr funPtr = (FunPtr)GetProcAddress(h, "Add");	//获取动态库里指定函数文件偏移首地址
		if (funPtr != NULL)
		{
			int result = funPtr(3, 3);	//调用函数
			printf("3 + 3 = %d \n", result);
		}
		else{
			printf("error add");
		}
	}

	printf("dd");
	getchar();

}

运行结果:

使用Visual Studio来创建动态库/静态库,并加载_第7张图片

下面来介绍一下上面用的三个函数:

LoadLibraryAFreeLibraryGetProcAddress函数是Windows为用户提供的用于载入动态库函数的接口

LoadLibraryA

函数原型:

HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);

_In_ LPCTSTR lpFileName:要加载的动态库路径

返回值:

成功返回引用模块句柄

FreeLibrary

函数原型:

WINBASEAPI
BOOL
WINAPI
FreeLibrary(
    _In_ HMODULE hLibModule
);
_In_ HMODULE hLibModule; LoadLibrary返回的动态库模块句柄

返回值:成功返回true,否则返回false

GetProcAddress

函数原型:

FARPROC GetProcAddress(
HMODULE hModule, // DLL模块句柄
LPCSTR lpProcName // 函数名
);

返回值:返回DLL模块文件中指定函数首地址/入口地址


除此之外也可以直接使用Visual Studio来包含DLL库,首先上面我们编译生成DLL的时候其实还有一个lib库文件:


使用Visual Studio来创建动态库/静态库,并加载_第8张图片

将lib库文件copy到我们的项目路径下,在将dll文件根据你的系统位数copySystem32/SysWOW64目录下

在项目属性里直接引用:

使用Visual Studio来创建动态库/静态库,并加载_第9张图片

在运行:

使用Visual Studio来创建动态库/静态库,并加载_第10张图片

运行结果:

使用Visual Studio来创建动态库/静态库,并加载_第11张图片

注意这里说一下为什么dll会生成lib文件?

Lib里面包含了dll的描述信息,比如函数符号表,偏移地址等信息,而非实际代码,所以我们在vside里面包含这个Lib文件,vs在编译器期间会自动读取lib配置信息,然后去系统指定动态库目录加载dll库!

编译器只会在编译时间用到lib文件来获取dll库里的某些信息,并不会被加载到程序当中!


静态库:

使用Visual Studio来创建动态库/静态库,并加载_第12张图片

添加.h和.cpp

使用Visual Studio来创建动态库/静态库,并加载_第13张图片

.h文件:

#pragma once //编译器命令 once头文件卫士

extern "C"/*以C的方式编译这段函数*/ __declspec(dllexport)/*将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。

											   */ int Add(int a, int b);

.cpp文件:

#include "libh.h"
int Add(int &a, int &b)
{
	return a + b;
}

生成:

使用Visual Studio来创建动态库/静态库,并加载_第14张图片

使用Visual Studio来创建动态库/静态库,并加载_第15张图片

使用编译器命令comment加载:

#include "libh.h"
#include 
#pragma comment(lib,"ConsoleApplication12.lib")           //加载静态库
int main(){
	
	
	int result = Add(3, 3);	//调用函数
	printf("3 + 3 = %d \n", result);
	printf("dd");
	getchar();

}

运行结果:

使用Visual Studio来创建动态库/静态库,并加载_第16张图片

相关连接:C/C++函数调用约定



你可能感兴趣的:(Windows核心编程,C/C++,Windows核心编程,c/c++)