C++之链接库的生成与使用

1、创建静态链接库

C++之链接库的生成与使用_第1张图片
创建完成后结构如下:
C++之链接库的生成与使用_第2张图片
创建完毕后新建一个头文件用于声明函数或类,并将其添加到pch.h文件中,为了看起来清晰明了建议头文件名称与项目名称保持一致,如:
C++之链接库的生成与使用_第3张图片
函数或类的实现代码写在StaticLib.cpp文件中,如:
C++之链接库的生成与使用_第4张图片
成功生成解决方案后如下:
C++之链接库的生成与使用_第5张图片

2、调用静态库

调用静态链接库需要用到xxx.h和xxx.lib文件。新建工程,并调用lib,如下所示:
C++之链接库的生成与使用_第6张图片
运行结果:
在这里插入图片描述
静态链接库的缺点:使用静态链接生成的可执行文件体积较大,造成浪费

3、创建动态链接库

C++之链接库的生成与使用_第7张图片
创建完成后结构如下:
C++之链接库的生成与使用_第8张图片
创建完毕后在DynamicDll.h文件中声明需要导出的函数或类,如:
C++之链接库的生成与使用_第9张图片

函数或类的实现代码写在DynamicDll.cpp文件中,如:
C++之链接库的生成与使用_第10张图片
成功生成解决方案后如下:
C++之链接库的生成与使用_第11张图片

4、调用动态链接库

方式一:隐式调用

隐式调用动态链接库需要用到xxx.h、xxx.lib以及xxx.dll文件。新建工程,调用lib,并将xxx.dll文件放至工程目录下,如:
C++之链接库的生成与使用_第12张图片
运行结果:
在这里插入图片描述

方式二:显式调用

显式调用动态链接库需要用到xxx.h和xxx.dll文件。新建工程,利用函数指针调用导出的函数,并将xxx.dll文件放至工程目录下,如:
C++之链接库的生成与使用_第13张图片
运行结果:
在这里插入图片描述
造成这样结果的原因是我们没有声明函数导出方式(C语言/C++),Visual Studio默认以C++的方式导出函数,函数编译名与函数定义名不相同,随着不同的调用规范而有所不同,因此会因为找不到对应的函数名而获取不到函数地址。extern "C"可以指定函数以C语言的方式导出,函数编译名与函数定义名相同。
在这里插入图片描述
当我们在导出函数前加上extern "C"声明后运行结果:
在这里插入图片描述
注意:对于C++类的导出,当成员函数没有输入参数时也可以直接通过函数地址动态调用,但当成员函数有输入参数时无法直接通过函数地址动态调用,因为成员函数存在一个隐形的输入参数this指针。因此,对C++类的导出需要增加一个仅存在虚函数的基类作为借口供外部调用。

5、函数调用规范

1、__declspec

_declspec(declaration specification)表示声明规范,主要是用于说明dll的导出、导入函数的规范,如_declspec(dllexport)、_declspec(dllimport)。

2、__cdecl

__cdecl(c declaration)是C/C++函数默认的调用规范,参数从右向左依次传递,压入堆栈,由调用函数负责恢复栈顶指针。

3、__stdcall

__stdcall(standard call),参数从右向左依次传递,并压入堆栈,由被调用函数清退堆栈,当函数有可变个数参数,自动转化为__cdecl调用规范。

4、__fastcall

__fastcall(fast call),顾名思义调用时会比其它调用约定快一点,因为其参数会利用寄存器进行传递,但若有多个参数,寄存器不够了,其余参数会从右向左入栈,由被调用函数恢复栈顶指针。

C++编译器的函数名修饰规则

C++的函数名修饰规则内容更加丰富,包含函数名,返回值类型,参数类型等信息。不管__cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识和按照参数类型代号拼出的参数表。__stdcall参数表的开始标识是“@@YG”,__cdecl参数表的开始标识则是“@@YA” ,__fastcall参数表的开始标识则是“@@YI”。参数类型代号如下:

字母 类型
X void
D char
E unsigned char
F short
H int
I unsigned int
J long
K unsigned long
M float
N double
_N bool
PA 指针

PA–表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复;参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束

你可能感兴趣的:(C++,c++,开发语言,c语言)