• extern “C”原理,用法以及使用场景-2016.01.05


    1 问题提出

    在编程过程中,经常发现如下用法:

    #ifndef _FILE_NAME_H_ 
    #define _FILE_NAME_H_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    ......
    
    #ifdef __cplusplus
    }
    #endif
     
    #endif

    这样的代码到底是什么意思呢?首先,__cplusplus是cpp中自定义的宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码。

    要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等。而在C中,只是简单的函数名字而已,不会加入其他的信息,也就是说:C++和C对产生的函数名字的处理是不一样的,extern "C"的目的就是主要实现C与C++的相互调用问题。

    2 c++中调用c函数

    使用场景:

    1、 由于系统内核一般是使用C语言来编写的,系统内核中用C语言实现了很多库。而上层应用程序有可能是用C++来开发,如果在内核库函数头文件中不用 extern “C”来声明库函数的话,在编写C++应用程序时,包含库头文件,在C++文件链接时就会以C++标准来链接库的函数名,而在库文件实现时是用C来实现的,二者函数名不同,在链接时就会出现找不到函数的现象。

    2、在个人开发工程中,个人熟悉使用c++语言,当.cpp文件要调用.c文件中的函数时,需要extern "C"声明.c文件中的函数,在cpp文件中让c++编译器使用c标准链接c文件中函数。

    具体实现:

    C函数头文件实现:

    //c.h
    #ifndef _c_h_
    #define _c_h_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void c_fun();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    C函数源文件实现:

    #include "c.h"
    
    void c_fun()
    {
    
    }

    C++调用C函数实现:example.cpp中调用c_func函数,

    //example.cpp实现
    
    #include "c.h"
    int main()
    {
         c_fun();
         return 0;
    }

    3 c中调用c++函数

    当extern “C”放在函数声明之前,并不会改变函数的编译方式,只是指定编译器按照C的标准链接,而不是按照C++的标准去链接函数。因此,如果c++的库要给c调用,显然,不但要在c++头文件中用该宏和extern "c"括起,在cpp中也要这么做。原因就是让cpp编译器将那些代码,编译成c风格。(在Visual Stduio 2010环境中,在c++函数源文件中不使用extern "c",编译出来的函数名字也是按照c风格,而不是c++风格,与前面的在cpp中也需要添加extern "c"不一致,留待后面论证。)

    c++函数头文件实现:

    #ifndef _cpp_h_
    #define _cpp_h_
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void cpp_fun();
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif

    c++函数源文件实现:

    #include "cpp.h"
    
    extern "C" {    //告诉C++编译器,扩号里按照C的命名规则编译
    void cpp_fun()
    {
    
    }
    }

    在c中调用c++函数,example.c调用cpp_fun函数:

    //example.c实现
    
    #include "cpp.h"
    
    int main()
    {
         cpp_fun();
         return 0;
    }

    上述方案只适合调用C++中的非成员函数,如果你想要在 C 里调用成员函数(包括虚函数),则需要提供一个简单的包装(wrapper)。具体方案参考如下博文:

    C如何调用C++中函数

    4 参考资料

    http://blog.csdn.net/hxg130435477/article/details/6632954

    http://blog.csdn.net/miyunhong/article/details/4589541

  • 相关阅读:
    淘宝的样式初始化
    手机上 input submit ios和andirod样式不统一
    css实现div左侧突出一个带边框的三角形
    git不提交某个文件
    判断一个对象是否是数组
    操作对象的几种方法
    LWIP互联网资料汇总
    stm32 看门狗
    SPI协议再读
    每天要做的事
  • 原文地址:https://www.cnblogs.com/zhouLee/p/5102533.html
Copyright © 2020-2023  润新知