C语言与C混合开发命中会遇见的ext

北京中科白癜风“平安医院” http://m.39.net/pf/a_7805810.html

这个系列进行到这里,我们完成了main方法的本质,命令行参数怎么解析,编译过程,指针的反向思考,以及extern的用途,静态库动态库的拆解,可变参数,static的妙用,inline的内联意义,const为啥还能改?

这一节我们来看下一个好玩的内容,就是C和C++的混合编程,我们来逐步拆解,就能够明白。

回顾下之前的内容,我们的源码,会经历预处理,编译,汇编,链接,而C与C++最终相遇,要解决的问题,会在链接过程遇到,我们来看下具体代码:

add.c

对应的头文件:add.h

然后hello.cpp,这里我们把后缀改成cpp了,代码如下:

引用了add函数,那么我们编一下,看看结果吧。

gcc-oadd.o-cadd.c

gcc-ohello.o-chello.cpp

gccadd.ohello.o-ohello

链接出错,我们看下出错信息:

可是我们明显链接了add.o,那么原因是什么呢?我们揭开hello.o,一探究竟。我们使用readelf-shello.o,来看下它的符号表,

发现了一个神奇的地方,UND未定义,后面跟着是个_Z3addii,这个跟我们add.o里面导出去的符号不一致,所以链接失败了。

这里就是这一节要讲的,cpp编译生成的目标文件中的符号定义,跟c生成出来的有区别,符号命名的方式不一样。这里是add.o里面add符号,可以发现不一样。

那么今天的主角就出现了,extern"C",它在解决什么问题?它在解决符号该如何去生成,这里指定让cpp中引用的对应函数,能够以C语言的方式去编译,汇编。

于是,我们就可以这样子处理下,把add.h修改下:

这里我们让引用它的地方,按照C语言的方式生成符号,我们这样子重新编译:

gcc-ohello.o-chello.cpp

gccadd.ohello.o-ohello

发现编译过了,也能运行了。是不是发现很简单?这就是我想讲的内容,抽丝剥茧,从本质解决问题出发,来剖析每个语法,关键字的意义,这样子才是真正的去思考,掌握语言的魅力!

这里想说的是,extern"C"这个玩意C源码引用是无法解析的,因为这个是C++特定的,所以这个头文件要做一个修订,

我们补充一个定义,用这个包含起来,这个定义是gcc在处理c++的源码时候,会去定义的一个值。而处理C源码不定义,自然就绕过了extern"C".

那么同样的道理,如果是C想调用C++的呢?C++的函数前面标记extern"C",就会变成C可以调用的。

当然这里还想说的是,C++的对外,extern"C",一般是独立出去,单独的一个实现,用来做C和C++内部的桥梁。

好了,今天就讲到这里,相信大家一下子也听明白了。下一节我们来讲下volatile关键字的用法,以及它的作用,C相关的关键点,说了一部分,我们讲完这些,就会进入项目实战,大家


转载请注明:http://www.aierlanlan.com/rzdk/355.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了