C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库

目录
函数重载
定义
举例
函数
注意
原因
c:
c++:
总结
创建一个C的静态库
将一个栈封装成一个静态库
c++调用c++库和c库
头文件包含
配置静态库
原因
c++调用c++库
c++调用C库
c调用c库和c++库
创建cpp的栈的静态库
更改库的配置
c调用c库
c调用c++库
为什么还是链接不上呢?
怎么才能链接成功呢?
原因
第一种
? 第二种
? 总结

函数重载 定义

是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
举例 同名的函数,参数类型不同,那么构成重载函数,在c++中可以顺利运行
#include using namespace std; int Add(int left, int right) { return left + right; }double Add(double left, double right) { return left + right; }int main() { cout << Add(1,2) << endl; cout << Add(1.3, 2.4) << endl; return 0; }

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

在c中运行失败:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

函数
double compare(int,int)

重载函数有:
int compare(double,double)double compare(double,double)double compare(double,int)double compare(int,double)//……………………等等

注意
只与形参的类型,顺序,个数有关,与返回的类型无关,只要参数的类型、顺序、大小和原函数有所区别,那么返回类型可以任意,都构成重载函数。
若函数的参数类型,大小,顺序与原函数相同,但是返回类型不同,是不构成重载函数的
double compare(int,int)int compare(int,int)//不构成

原因 在vs环境下不好区分,在Linux环境下编译区别:
c:
c的编译器中,对函数的命名规则:
直接用我们给定的函数名进行编译
重载函数的函数名相同,编译时会发生访问冲突
c++:
c++的编译器中,对函数的命名规则:
_Z + 函数名长度 + 函数名 +参数类型的首字母
即使函数名相同,命名规则保证了编译时每个函数名的唯一性
访问不会发生冲突
总结
在c中,链接时,c中的函数名是直接以我们给的函数名确定的。
而在c++中,函数名的命名规则是_Z + 函数名长度 + 函数名 +参数类型的首字母
即使函数名相同的两个函数,只要符合重载条件,在c++中调用不会发生冲突。
因为函数名命名规则不同,c不支持函数重载。
无论在那个环境下,c++保证了重载函数函数名的唯一性。
创建一个C的静态库 将一个栈封装成一个静态库 将已经写好的栈的声明和定义在VS中打开,此时没有主函数,运行时编译器将项目当成一个可执行文件,进行运行,会报错,如下图:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

接下来我们开始对此进行封装:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
完成后进行运行,如下图所示:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

在此项目对应的文件下,就能找到封装的静态库:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

c++调用c++库和c库 头文件包含 创建一个.cpp的项目,在主函数中用栈中的函数创建栈,初始化栈,销毁栈,如下图:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

项目识别不了我们的操作。
这里我们包含头文件必须要包含到栈的头文件才行,不在一个项目中,我们使用相对路径解决这个问题:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

接下来我们包含头文件,要用到相对文件路径,直接在文件目录中找栈的头文件,从上图路径开始,向上一层,没有找到:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

再向上一层,找到关于栈的静态库文件:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

进入此路径下,找到此文件:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

进入此文件下,找到栈的头文件:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

包含头文件过程如下:
#include "../../Stack_C.lib/Stack_C.lib/Stack.h"

. . 是跳到上级目录,如上图,我们向上跳了两次,找到了静态库的文件,接下来就是正常的在路径下找头文件。包含头文件后,就可以识别对栈相关的操作:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
运行一下,发现失败:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

直接调用c库会失败,这里还需要进行配置
配置静态库如下图操作:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

点击编辑,进行如下图操作:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

效果如下:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

之后,在静态库的文件下,在Debug下,找到静态库,将其文件名包括后缀都复制下来
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

再次运行:
依旧是无法链接
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

原因
c库中函数的命名就是以我们给的函数名,而c++中的命名规则是_Z + 函数名长度 + 函数名 + 参数类型的首字母,进行完预编译,编译和汇编后,进行链接时,c++在c库中找不到对应的函数名,因此链接失败。
c++调用c++库 若我们将Stack.c改为Stack.cpp,运行一次,这样刚刚的c静态库,就会更新成c++的静态库
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

之后再运行test.cpp ,此时就是c++调用c++的静态库了
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

我们将Stack.cpp,改回来Stack.c,再次运行生成c的静态库
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

c++调用C库 那么我想要用c++来调用c的静态库怎么办?
用到 entern"C",这是C++中的语法。
告诉编译器,用的是C库,用C的方式去链接,这样就可以链接成功。
extern "C" { #include "../../Stack_C.lib/Stack_C.lib/Stack.h" }

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

c调用c库和c++库 创建cpp的栈的静态库 C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

生成解决方案,在相对路径中可以找到该静态库
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
创建新的.c源文件,对其头文件路径进行更改
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

更改库的配置 C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
此时库配置完毕。
c调用c库 C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

此时,运行test.c,就是c调用c库
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

c调用c++库 将Stack.c改回Stack.cpp,生成解决方案,静态库变回c++的静态库,运行test.c,就是c调用c++的静态库,如下:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

为什么还是链接不上呢? 原因和c++直接调用c库链接不上的原因相同,c和c++库中,对函数的命名规则不同,c在c++的静态库中找不到对应的函数名,因此链接失败。
有同学可能会说,在test.c中用 extern ,试试,这个语法是c++中的,不能在c中调用,想法不成立。
怎么才能链接成功呢?
既然 entern 是c++的语法,那么我们把entern "C",就用在 Stack.cpp 中,再生成解决方案,更新c++的静态库。
告诉编译器在c++的静态库中用C的方式去修饰这些函数。
如下:
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

再次运行test.c :
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

原因
头文件展开时,会将entern "C" ,放入test.c中,c识别不了这个语法,因此运行不通过。
但是思想是正确的,怎么样才能让 entern "C" 在 .cpp中出现,在.c中消失呢?
这里可以用条件编译来解决:
第一种
C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
第二种
【C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库】C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片

C++笔记|c++入门(二)函数重载 --- c和c++中相互调用对方的静态库
文章图片
总结
更推荐第一种,直接用entern "C" ,包含所有函数,当函数很多时,更加高效!
c调用c++库,c++调用c库,都是在c++中做出调整,按c的规则对函数进行修饰!
链接失败的原因就是c++和c对函数的命名规则不同,这也是c++支持函数重载的原因!

    推荐阅读