C++和C相互调用-extern "C"的使用

   一、C++调用C

实际工程中C++和C代码相互调用是不可避免的

1.C++编译器能够兼容C语言的编译方式
2.C++编译器会优先使用C++编译的方式
3.extern关键字能强制让C++编译器进行C方式的编译

语法:

extern "C"
{
      //do C-style compilation here
}

Example:

C语言文件 add.c  :


#include "add.h"



int add(int a, int b)

{

    return a + b;

}

C++文件  main.h:

int add(int a, int b);

C++文件  main.cpp:

#include <stdio.h>

extern  "C"   //头文件中的代码为C代码,所以必须用C方式编译。 
{
	#include "add.h"
}

int add(int a, int b)

{
	int c = add(1,2);
	
	printf("c = %d\n",c);

    return 0;

}

   extern "C"在C++中有一个函数名,它有“C”链接(编译器不会mangle 这个函数名),这样client C代码就可以链接到你的函数使用一个“C”兼容的头文件,它只包含你的函数的声明。你的函数定义包含在一个二进制格式(由你的C++编译器编译),client C'链接器将会链接到使用'C'的名称。

    由于C ++有函数名称的重载而C没有,因此C ++编译器不能只使用函数名作为链接的唯一id,因此它通过添加有关参数的信息来mangle 函数名。 AC编译器不需要破坏名称,因为您不能在C中重载函数名。当您声明函数在C ++中具有extern“C”链接时,C ++编译器不会将参数/参数类型信息添加到用于函数名的连接。

    这样你就知道,你可以显式地指定每个单独的声明/定义的“C”链接,或者使用一个block来对声明/定义的序列进行分组,以获得一个特定的链接:

extern "C" void foo(int);
extern "C"
{
   void g(char);
   int i;
}

   如果你比较 关心技术方面的问题,它们列在C++03标准的第7部分中,这里有一个简短的总结(强调extern “C”):

1.extern “C”是一个链接规范
2.每个编译器都需要提供“C”链接
3.链接规范只在名称空间范围内发生
4.只有函数名和带有外部链接的变量名具有语言链接
5.具有不同语言连接的两个函数类型是不同的类型,即使在其他情况下是相同的
6.链接规范nest,内部决定了最终的链接
7.对于类成员来说,外部的“C”是被忽略的
8.在大多数带有特定名称的函数中,可以有“C”链接(不管名称空间)
9. 'static' inside 'extern "C"'“是有效的;一个被声明的实体有内部链接,因此没有语言链接
10.从C++到其他语言中定义的对象,以及从其他语言中定义的对象,都是由实现定义和依赖于语言的。只有当两种语言实现的对象布局策略足够相似时,才可以实现这样的链接

 二、如何使C语言代码既能在C编译中通过,又能在C++编译中通过?

语法:

#ifdef __cplusplus
extern "C" {
#endif

// all of your legacy C code here

#ifdef __cplusplus
}
#endif

  这样做的目的是让您可以使用C++代码使用C头文件,因为将定义宏“cplusplus”。但是您仍然可以在遗留C代码中使用它,在那里没有定义宏,所以它不会看到唯一的C++结构。

Test:

#include <stdio.h>

#ifndef __cplusplus //如果没有定义宏
extern  "C"         //保留extern "C"
{
#endif

	#include "add.h"

#ifdef __cplusplus    //如果定义了宏
}                     //保留括号 }
#endif     

int add(int a, int b)

{
	int c = add(1,2);
	
	printf("c = %d\n",c);

    return 0;

}

<全文完>

参考资料:

1)唐佐林《C++深度解析教程》

2)stackoverflow

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值