平时我们在linux c平台开发的时候,引用了一些Cpp或者C的代码库,发现一些头文件有如下代码条件编译。

#ifdef  __cplusplus
extern "C" {
#endif // 代码 #ifdef __cplusplus
}
#endif

这个是什么意思呢?一开始看到这个也很茫然。上网查找了一些资料。

主要作用:

为了在C++代码中调用用C写成的库文件,就需要用extern"C"来告诉编译器:这是一个用C写成的库文件,请用C的方式来链接它们。

原因:

C++支持函数重载,而C是不支持函数重载的,两者语言的编译规则不一样。编译器对函数名的处理方法也不一样。

假设有这个一个函数原型:

void func(int a,int b)
{
//code
}

可能在C++编译之后会产生_func_int_int之类的名字,因为C++支持重载。而C编译之后,可能为_func。

关键字:extern "C" 表示编译生成的内部符号名使用C约定

//C++引用C函数的例子
//test.c
#include <stdio.h>
void mytest()
{
printf("mytest in .c file ok\n");
}
//main.cpp
extern "C"
{
void mytest();
}
int main()
{
mytest();
return ;
}
//在C中引用C++函数
//在C中引用C++语言中的函数和变量时,C++的函数或变量要声明在extern "C"{}里,但是在C语言中不能使用extern "C",否则编译出错。
//test.cpp
#include <stdio.h>
extern "C"
{
void mytest()
{
printf("mytest in .cpp file ok\n");
}
}
//main.c
void mytest();
int main()
{
mytest();
return ;
}
//综合使用
//一般我们都将函数声明放在头文件,当我们的函数有可能被C或C++使用时,我们无法确定是否要将函数声明在extern "C"里,所以,我们应该添加
#ifdef __cplusplus
extern "C"
{
#endif
//函数声明
#ifdef __cplusplus
}
#endif

如果我们注意到,很多头文件都有这样的用法,比如string.h,等等。

//test.h
#ifdef __cplusplus
#include <iostream>
using namespace std;
extern "C"
{
#endif
void mytest();
#ifdef __cplusplus
}
#endif

这样,可以将mytest()的实现放在.c或者.cpp文件中,可以在.c或者.cpp文件中include "test.h"后使用头文件里面的函数,而不会出现编译错误。

//test.c
#include "test.h"
void mytest()
{
#ifdef __cplusplus
cout << "cout mytest extern ok " << endl;
#else
printf("printf mytest extern ok n");
#endif
}
//main.cpp
#include "test.h"
int main()
{
mytest();
return ;
}

参考博文:

http://www.cnblogs.com/HappyXie/archive/2011/01/07/1929369.html

“#ifdef __cplusplus extern "C" { #endif”的定义的更多相关文章

  1. “#ifdef __cplusplus extern "C" { #endif”的定义-----C和C++的互相调用

    "#ifdef __cplusplus extern "C" { #endif"的定义 看一些程序的时候老是有 "#ifdef __cplusplus ...

  2. #ifdef __cplusplus extern "C" { #endif”的定义的含义

    看一些程序的时候老是有“#ifdef __cplusplusextern "C" {#endif”的定义,搞搞清楚是怎么回事: Microsoft-Specific Predefi ...

  3. 备忘录:“#ifdef __cplusplus extern "C" { #endif”的定义

    看一些程序的时候老是有“#ifdef __cplusplusextern "C" {#endif”的定义,搞搞清楚是怎么回事: Microsoft-Specific Predefi ...

  4. #ifdef __cplusplus extern "C" { #endif”的定义

      平时我们在linux c平台开发的时候,引用了一些Cpp或者C的代码库,发现一些头文件有如下代码条件编译. #ifdef __cplusplus extern "C" { #e ...

  5. #ifdef __cplusplus extern c #endif 的作用

    #ifdef __cplusplus // C++编译环境中才会定义__cplusplus (plus就是"+"的意思) extern "C" { // 告诉编 ...

  6. #ifdef __cplusplus extern "C" { #endif

    1.在好多程序中我们会遇到下面代码段 #ifdef __cplusplus        extern "C" {        #endif //c语法代码段 #ifdef __ ...

  7. #ifdef __cplusplus extern "C" { #endif 的解释

    好多程序中都会遇到下列代码段: #ifdef __cplusplus extern "C" { #endif /****************** C语法代码段 ******** ...

  8. C++ 为什么要使用#ifdef __cplusplus extern "C" { #endif

    转载:http://www.cnblogs.com/ayanmw/archive/2012/03/15/2398593.html 转载:http://blog.csdn.net/zkl99999/ar ...

  9. undefined reference to `recvIpcMsg(int, ipc_msg*)'——#ifdef __cplusplus extern "C" { #endif

    最近在弄一个进程间通信,原始测试demon用c语言写的,经过测试ok,然后把接口封装起来了一个send,一个recv. 使用的时候send端是在一个c语言写的http服务端使用,编译ok没有报错,但是 ...

随机推荐

  1. FPGA那些事 --经典总结

    规范很重要 工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的.逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现有错,回头再看自 ...

  2. 检测IIS应用程序池对象 回收

    function RecycleYourAppPool([string] $poolName){ Import-Module WebAdministration #获取所有Application Po ...

  3. API认证方法一览

    Open api authentication Amazon DigitalOcean Webchat Weibo QQ Amazon Web Services HMAC Hash Message A ...

  4. ie版本判断的js hack

    常用来判断各种浏览器版本的 ie js hack如下: 1. <!–[if !IE]><!–> 除IE外都可识别 <!–<![endif]–> 2. < ...

  5. HDU_2024——判断字符串是否是c语言合法标识符

    Problem Description 输入一个字符串,判断其是否是C的合法标识符.   Input 输入数据包含多个测试实例,数据的第一行是一个整数n,表示测试实例的个数,然后是n行输入数据,每行是 ...

  6. java与数据结构(3)---java实现循环链表

    循环链表:将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单链表循环表,即循环链表. 循环链表与单链表最重要的区别是:尾结点的指针,不再是p->n ...

  7. 你应该了解的 7个Linux ls 命令技巧

    在前面我们系列报道的两篇文章中,我们已经涵盖了关于‘ls’命令的绝大多数内容.本文时‘ls命令’系列的最后一部分.如果你还没有读过该系列的其它两篇文章,你可以访问下面的链接. 15 个‘ls’命令的面 ...

  8. Python初体验_基础(一)

    一:变量 变量的赋值: name = "Meng" 上述代码声明了一个变量,变量名为name,变量name的值为:"Meng" 变量定义: 一个在内存存数据的容 ...

  9. 数组对象元素的添加,String对象,BOM对象以及文档对象的获取

    数组对象的删除有三种方法: pop();        //移除最后一个元素并返回该元素值shift();      //移除最前一个元素并返回该元素值,数组中元素自动前移splice(0,2); / ...

  10. [深入React] 7.组件生命周期

    生命周期一共分三段:初始化,运行中,销毁.按照顺序: 初始化 getDefaultProps():Object 全局只会调用一次,为当前类生成的默认props,会被父组件传入的同名props覆盖. g ...