平时我们在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 0;
}
//在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 0;
}
//综合使用
//一般我们都将函数声明放在头文件,当我们的函数有可能被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 0;
}

参考博文:

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" { #end ...

  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. linux shell脚本之-变量极速入门与进阶(1)

    1,如果创建shell脚本? 使用任意文本编辑软件,一般为vim,创建.sh结尾的文件,在文件的最开头用 #!/bin/bash 注明shell的类型 如: ghostwu@dev:~/linux/s ...

  2. 微信小程序Map组件踩坑日记

    刚刚又发生一个bug,搞得我头皮发麻,本来该美滋滋的回家准备度过愉快的周末,瞬间变成了日常修bug,来,开始填坑之路 情景再现: 首先说一说我们项目的需求, 点击下方,弹出抽屉 点击对应的地图打开相应 ...

  3. 【代码笔记】Web-HTML-布局

    一, 效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  4. VUE 实现复制内容到剪贴板功能

    注: 依赖第三方插件 clipboard 一.安装插件 npm install vue-clipboard2 --save 二.全局注入(main.js) import VueClipboard fr ...

  5. Linux 学习笔记之超详细基础linux命令 Part 5

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 4----------------- ...

  6. Jni 线程JNIEnv,JavaVM,JNI_OnLoad(GetEnv返回NULL?FindClass返回NULL?)

    此文章是关于NDK线程的第二篇理论知识笔记.主要有两个点,如下: 1.pthread_create(Too many arguements, expected 1) ?2.线程中如何获取JNIEnv? ...

  7. Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版

    描述: 之前有做过一个记账本APP,拿来练手的,做的很简单,是用Eclipse开发的: 最近想把这个APP重新完善一下,添加了一些新的功能,并选用Android Studio来开发: APP已经完善了 ...

  8. django 简单路由配置

    Django==2.0.1 版本路由配置: 1.在manage.py同级目录下新建一个应用app1 在app1下新建urls.py文件,定义一个app1的空白路由: from django.urls ...

  9. iptable用法

    一:添加屏蔽IP #禁止此IP访问服务器iptables -I INPUT -s 1.2.3.4 -j DROP或iptables -A INPUT -s 1.2.3.4 -j DROP#禁止服务器访 ...

  10. Linux命令大全总结

    目录方面的命令:ls,dir,cd,clear,mkdir ls 显示指定目录的文件和目录 ls -a 列出目录下的所有文件,包括以 . 开头的隐藏文件 ls -l 显示指定目录的详细列表 ls -R ...