c与c++的相互引用

来源:互联网 发布:淘宝仓库配货员累吗 编辑:程序博客网 时间:2024/05/16 08:28

  • c++在引用c程序的时候,需要加上extern“C”(意思就是按照c的规范编译),这句话在很多书上,网络博客上都有见到。但为什么要这样加,什么时候要加这个?我之前很少想过,只是把这个当做一个“知识” 记着。其实,确切的说,在我脑海里,没有c,c++之间区别的概念。深甚至认为只是简单后缀的不同,自从接触了linux编译c/c++,才有所认识。实际上编译器会根据后缀名来对语言做出判别,但我们也可以潜行队编译器指定:g++ -x c++ test.txt -o test
    c与c++所使用的编译器不同,因此产生的目标代码也会有所不同,请看下面一段代码
int test_add(int x,int y){  return x+y;}

只是一个简单的函数,下面我们分别用gcc和g++把它编译成汇编代码:

    .file   "a.c"    .text.globl test_add    .type   test_add, @functiontest_add:    pushl   %ebp    movl    %esp, %ebp    movl    12(%ebp), %eax    movl    8(%ebp), %edx    leal    (%edx,%eax), %eax    popl    %ebp    ret    .size   test_add, .-test_add    .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)"    .section    .note.GNU-stack,"",@progbits
    .file   "a.cpp"    .text.globl _Z8test_addii    .type   _Z8test_addii, @function_Z8test_addii:.LFB0:    .cfi_startproc    .cfi_personality 0x0,__gxx_personality_v0    pushl   %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    movl    12(%ebp), %eax    movl    8(%ebp), %edx    leal    (%edx,%eax), %eax    popl    %ebp    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE0:    .size   _Z8test_addii, .-_Z8test_addii    .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)"    .section    .note.GNU-stack,"",@progbits

从上面两段代码中可以看出,产生的函数名有很大的区别,gcc产生的函数名为test_add, 而g++产生的函数名为_Z8test_addii。g++编译器之所以要在函数名加很多修饰,主要是为了实现函数重载。
-
有了上面的认识,就不难理解c++引用c为何要加extern“c“,确切的说是应引用c生成库文件,因为如果有源文件,我把源文件直接拷贝过来,在按照统一的标准编译。在引用库文件时,我们一般做法是加入相应库文件的.h头文件,这个头文件是c写的,那么在预处理,编译阶段,c++编译器就会把头文件中的函数名加上一定的修饰,但库文件中的函数名确是按照c的规范编译的,这样,在链接库文件时,就会找不到相应的文件名!!!

  • c c++相互引用的方法
  • (1)c++中引用c
    c++产生于c之后,因此,c++可以去兼容c,也就是说extern“C”这条语句在c++中是合法的,这样一来,我们调用c库就非常简单了,比如:库文件的函数在c.h 中定义,那么我们在c++的头文件中这样引用c的头文件:
extern "C"{ #include"c.h"} 

这样,c++编译器在编译程序时,遇到c.h中的函数,就会按照c的风格,不会对函数名加以修饰,这样在链接库文件时,就能找到库文件中的函数。

  • (2)c中调用c++
  • c中引用extern“C”是非法的,那么为了能让c应用c++的库文件,我们在写声明相应的c++函数时,就要加上extern“C”,这样编译器将按照c的规范编译,函数名也就不会变的那么“古怪”,在c中也就能够调用成功。c在声明相应函数时,就可以使用extern关键字,来表明这是一个外部函数,开始我在测试的时候,没加这个申明,也一样运行成功,这是因为我写的刚好是一个简单的函数,c编译器在程序员没有声明函数时,会默认添加一个声明,那如果这个默的和我们实际的不一样,那就容易出错。
0 0
原创粉丝点击