转载:http://www.cnblogs.com/ayanmw/archive/2012/03/15/2398593.html

转载:http://blog.csdn.net/zkl99999/article/details/48134621

转载: http://www.jianshu.com/p/5d2eeeb93590

经常看到别人的头文件 有这样的代码

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4.  
  5. // C 样式 的函数
  6.  
  7. #ifdef __cplusplus
  8. }
  9. #endif

为什么要这样呢?

因为C语言不支持重载函数,也就是同名函数,参数却不一样,C++支持,其编译器对函数名的处理方法不一样,导致 虽然都是C 样式的函数,不同编译器编译出来的不一样。

如果是C语言编译的中间文件,要C++ 来调用,那么就需要这个了,C++ 有了 extern "C" 就会按照 C 语言的方法进行函数命名。这样编译出来的中间文件就是C样式的函数名,C/C++ 都可以调用。

如果C++ 编译的中间文件,要C语言来调用,是不行的。这也就为什么DLL中常看见extern "C" {},windows是采用C语言编制他首先要考虑到C可以正确调用这些DLL,而用户可能会使用C++而extern "C" {}就会发生作用。

总结:

1.extern "C"表示编译生成的内部符号名使用C约定。

2.C++支持函数重载,而C不支持,两者的编译规则也不一样,函数被C++编译后在符号库中的名字与C语言的不同。

例如,假设某个函数的原型为: void foo( int x, int y ); 该函数被C编译器编译后在符号库中的名字可能为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不 同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。

例子:

test.h

  1. #ifndef _TEST_H_
  2. #define _TEST_H_
  3. #ifdef _cplusplus
  4. extern "c"
  5. {
  6. #endif
  7. extern int Add(int a, int b);
  8. extern int Sub(int a, int b);
  9.  
  10. #ifdef _cplusplus
  11. }
  12. #endif
  13.  
  14. #endif

test.c

  1. #include "test.h"
  2.  
  3. int Add(int a, int b)
  4. {
  5. return a + b;
  6. }
  7.  
  8. int Sub(int a, int b)
  9. {
  10. return a - b;
  11. }

main.cpp

  1. #include <stdio.h>
  2.  
  3. extern "C"
  4. {
  5. #include "test.h"
  6. }
  7.  
  8. int main()
  9. {
  10. printf("Add=%d\n",Add(,));
  11. printf("Sub=%d\n",Sub(,));
  12. return ;
  13. }

C++ 为什么要使用#ifdef __cplusplus extern "C" { #endif的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. LeetCode——Find Minimum in Rotated Sorted Array

    Description: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 ...

  2. Java初学者笔记六:反射

    Java反射基础 零.基础类代码 import java.io.*; import java.lang.reflect.*; class father{ public String fName; fa ...

  3. 使用HttpClient以文件流的方式上传文件(非multipartFormData方式)

    @Test public void testAdd() throws IOException { HttpPost post = new HttpPost("http://localhost ...

  4. 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树

    [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...

  5. 项目中启动另外的一个app

    NSMutableString *webViewContent = [[NSMutableStringalloc] init]; [webViewContent appendString:@" ...

  6. Swift - 获取当前系统时间

    // 获取当前系统时间 let date = NSDate() let timeFormatter = NSDateFormatter() timeFormatter.dateFormat = &qu ...

  7. 豆瓣api开发

    前面有说过豆瓣API的开发,在做一些开源项目的时候,很多时候会用到豆瓣API接口,拿过来做测试,现在只是对豆瓣API开发做一些简单的梳理: 豆瓣API开发的接口: https://developers ...

  8. Jenkins构建时提示maven版本问题

    在使用Jenkins进行项目构建的时候出现下面问题 [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were enc ...

  9. 【ArcGIS for SivlerLight api(3)】基础图层增删改查

    1.基础底图通常使用TiledLayer或者ArcGISDynamicLayer. 本质上都是在本地加载栅格图片.后台生成策略不同而已.从Vs2010的控件栏上拖过来的Map控件默认添加的底图是Esr ...

  10. Windows中杀死某个端口的进程

    最近写项目,总是出现端口被占用的问题,原来傻傻的把电脑重启一下,终于有一天受不了了,想要想办法解决.刚开始从网上找了好多教程,发现不行.开始自己尝试,终于,成功的将占用端口的进程杀掉.在此记录下过程( ...