c与c++的相互引用


  • 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, @function
test_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编译器在程序员没有声明函数时,会默认添加一个声明,那如果这个默的和我们实际的不一样,那就容易出错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值