zoukankan      html  css  js  c++  java
  • 你真的知道C语言里extern "C" 的作用吗?

    经常在C语言的头文件中看到下面的代码:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // all of your legacy C code here
    
    #ifdef __cplusplus
    }
    #endif
    

    这通常用于C++C混合编程的时候,为了防止C++的编译器在编译C文件的时候出现错误;
    众所周知,C++可以进行函数名重载,但是C则没有这种功能,那这和extern "C"又有什么关系呢?
    先看下面这个表格,如下所示;

    语言 描述
    C 函数名可以作为唯一ID和代码段的程序建立联系
    C++ 因为重载的关系,函数名符号会被破坏,从而会更加函数的参数不同而重新生成函数符号

    未添加 extern “C”

    test.h

    #ifndef TEST_H
    #define TEST_H
    
    void foo1(void);
    void foo2(void);
    void foo3(int i);
    
    #endif
    

    test.c

    
    void foo1(void){}
    void foo2(void) {}
    void foo3(int i){}
    
    int main(int argc,char** argv){
    	
    	foo1();
    	foo2();
    	foo3(1);	
    	return 0;
    }
    
    

    编译这两个文件,生成test.o文件,通过objdump查看函数符号;

    g++ -c test.c test.h
    objdump -t test.o
    

    可以看到函数符号已经被编译器修改了;
    在这里插入图片描述

    添加extern “C”

    test.h

    #ifndef TEST_H
    #define TEST_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void foo1(void);
    void foo2(void);
    void foo3(int i);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    test.c

    #ifdef __cplusplus
    extern "C" {
    #endif
    void foo1(void){}
    void foo2(void) {}
    void foo3(int i){}
    #ifdef __cplusplus
    }
    #endif
    
    int main(int argc,char** argv){
    	
    	foo1();
    	foo2();
    	foo3(1);	
    	return 0;
    }
    
    

    编译这两个文件,生成test.o文件,通过objdump查看函数符号;

    g++ -c test.c test.h
    objdump -t test.o
    

    这时候函数符号是正确的;
    在这里插入图片描述

    extern “C” 是告诉C++的编译器不要打我这些C函数的主意;参考这篇文章会更加详细。

  • 相关阅读:
    平时用到的Linux命令
    angular.element方法汇总
    CSS display:inline-block
    CSS:position:fixed使用(转)
    常见浏览器兼容性问题与解决方案【转】
    部分浏览器兼容问题
    php对应js math.random
    php stdclass转数组
    写在2016年末
    VirtualBox中Ubuntu 14.04屏幕分辨率不能设置的问题
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783360.html
Copyright © 2011-2022 走看看