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函数的主意;参考这篇文章会更加详细。

  • 相关阅读:
    Maven setting配置镜像仓库
    MyBatis配置Mapping,JavaType和JDBCType的对应关系,#与$区别
    Git常用命令
    Js JSON.stringify()与JSON.parse()与eval()详解及使用案例
    例:判断是不是自有属性hasOwnProperty方法
    JS中原型链中的prototype与_proto_的个人理解与详细总结
    原型理解:prototype
    JS中attribute和property的区别
    面试题术语
    函数语法
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783360.html
Copyright © 2011-2022 走看看