C语言与C++混合开发?命中会遇见的extern C!

原标题:C语言与C++混合开发?命中会遇见的extern"C"!

C语言与C++混合开发?命中会遇见的extern C!
文章图片
C语言与C++混合开发?命中会遇见的extern C!
C语言与C++混合开发?命中会遇见的extern C!
文章图片
这个系列进行到这里 , 我们完成了main方法的本质 , 命令行参数怎么解析 , 编译过程 , 指针的反向思考 , 以及extern的用途 , 静态库动态库的拆解 , 可变参数 , static的妙用 , inline的内联意义 , const为啥还能改?
这一节我们来看下一个好玩的内容 , 就是C和C++的混合编程 , 我们来逐步拆解 , 就能够明白 。
回顾下之前的内容 , 我们的源码 , 会经历预处理 , 编译 , 汇编 , 链接 , 而C与C++最终相遇 , 要解决的问题 , 会在链接过程遇到 , 我们来看下具体代码:
add.c

C语言与C++混合开发?命中会遇见的extern C!
文章图片
对应的头文件:add.h

C语言与C++混合开发?命中会遇见的extern C!
文章图片
然后hello.cpp , 这里我们把后缀改成cpp了 , 代码如下:

C语言与C++混合开发?命中会遇见的extern C!
文章图片
引用了add函数 , 那么我们编一下 , 看看结果吧 。
gcc-oadd.o-cadd.c
gcc-ohello.o-chello.cpp
gccadd.ohello.o-ohello
链接出错 , 我们看下出错信息:

C语言与C++混合开发?命中会遇见的extern C!
文章图片
可是我们明显链接了add.o , 那么原因是什么呢?我们揭开hello.o,一探究竟 。 我们使用readelf-shello.o , 来看下它的符号表 ,

C语言与C++混合开发?命中会遇见的extern C!
文章图片
发现了一个神奇的地方 , UND未定义 , 后面跟着是个_Z3addii , 这个跟我们add.o里面导出去的符号不一致 , 所以链接失败了 。
这里就是这一节要讲的 , cpp编译生成的目标文件中的符号定义 , 跟c生成出来的有区别 , 符号命名的方式不一样 。 这里是add.o里面add符号 , 可以发现不一样 。

C语言与C++混合开发?命中会遇见的extern C!
文章图片
那么今天的主角就出现了 , extern"C" , 它在解决什么问题?它在解决符号该如何去生成 , 这里指定让cpp中引用的对应函数 , 能够以C语言的方式去编译 , 汇编 。
于是 , 我们就可以这样子处理下 , 把add.h修改下:

C语言与C++混合开发?命中会遇见的extern C!
文章图片
这里我们让引用它的地方 , 按照C语言的方式生成符号 , 我们这样子重新编译:
gcc-ohello.o-chello.cpp
gccadd.ohello.o-ohello
发现编译过了 , 也能运行了 。 是不是发现很简单?这就是我想讲的内容 , 抽丝剥茧 , 从本质解决问题出发 , 来剖析每个语法 , 关键字的意义 , 这样子才是真正的去思考 , 掌握语言的魅力!
这里想说的是 , extern"C"这个玩意C源码引用是无法解析的 , 因为这个是C++特定的 , 所以这个头文件要做一个修订 ,

C语言与C++混合开发?命中会遇见的extern C!
文章图片
我们补充一个定义 , 用这个包含起来 , 这个定义是gcc在处理c++的源码时候 , 会去定义的一个值 。 而处理C源码不定义 , 自然就绕过了extern"C".
那么同样的道理 , 如果是C想调用C++的呢?C++的函数前面标记extern"C" , 就会变成C可以调用的 。
当然这里还想说的是 , C++的对外 , extern"C" , 一般是独立出去 , 单独的一个实现 , 用来做C和C++内部的桥梁 。
好了 , 今天就讲到这里 , 相信大家一下子也听明白了 。 下一节我们来讲下volatile关键字的用法 , 以及它的作用 , C相关的关键点 , 说了一部分 , 我们讲完这些 , 就会进入项目实战 , 大家关注 , 不掉队!
喜欢 , 帮忙转发~~
授课示范
配套教材

C语言与C++混合开发?命中会遇见的extern C!
文章图片