extern "C"学习笔记

extern “C” 学习记录

学习记录类博客,用于记下学过的一些内容或者解决过的一些问题,便于将来重新检索。

extern "c"

  1. extern的作用
    extern 是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块和其它模块中使用。
    extern 用在变量或函数前面,用来说明函数或变量是在别处定义的,在此处引用。
    关于extern, 这里引用博客:
    C语言中extern的用法

extern修饰变量的声明。

举例:若a.c中需引用b.c中的变量int v,可以在a.c中声明extern int >v,然后就可以引用变量v;需要注意的是,被引用的变量v的链接属性必须是外链接(external)的,也就是说a>.c要引用到变量v,不只是取决于在a.c中声明extern int >v,还取决于变量v本身是能够被引用到的。这里涉及到另外一个话题—变量的作用域。能够被其他模块以ex>tern引用到的变量通常是全局变量。

还有一点是,extern int >v可以放在a.c中的任何地方,比如可以在a.c中函数func()定义的开头处声明extern int >v,然后就可以引用到变量v了,只不过这样只能在func()作用域中引用变量v(这还是变量作用域的问题,对于这一点来说,很多人使用时都心存顾虑,好像extern声明只能用于文件作用域似的)。
extern修饰函数的声明。

本质上讲,变量和函数没有区别。函数名是指向函数二进制块开头处的指针。如果文件a.c要引用b.c中的函数,比如在b.c中原型是int func(int m),那么就可以在a.c中声明extern int func(int m),然后就能使用func()来做任何事情。就像变量的声明一样,extern int func(int m)可以放在a.c中的任何位置,而不一定非要放在a.c的文件作用域的范围中,

对其他模块中函数的引用,最常用的方法是包含这些函数声明的头文件。使用extern和包含头文件来引用函数的区别:extern的引用方式比包含头文件要间接得多。extern的使用方法是直接了当的,想引用哪个函数就用extern声明哪个函数。这大概是kiss原则的一种体现。这样做的一个明显的好处是,会加速程序的编译(确切地说是预处理)的过程,节省时间。在大型C程序编译过程中,这种差异是非常明显的。

  1. extern "c"的使用
    extern "c"是C++中的一个特性,主要作用是用来实现在C++中调用C语言的函数,实现兼容。出现的主要原因是因为C++编译器和C编译器对于函数或者变量的命名规范的不同,由于C++中多态的特性,C++中函数可以重载,因而函数签名包括了函数参数,而C语言不能重载,从而函数签名只有函数名。在C++中,部分编译器重命名时,采用的是将参数类型附在名称后面,而C则是直接用名称。
    假如不使用extern "c"特性,在引用C语言的函数时,采用C++编译器,比如linux下用g++编译的话,则可能将其重命名为带有类型,链接时与原c文件编译产生的命名不符,可能造成错误。

  2. "extern "C"使用例子
    这里给出extern "C"使用的例子,参考于两篇博客:
    C++中为什么有时要使用extern “C”
    extern “C”的作用详解

A.h

    #ifndef _A_H
    #define _A_H

    int A(int a, int b);
    
    #endif

A.c

    #include "A.h"
    
    int fun(int a, int b)
    {
        return a + b;
    }

B.h

    #ifndef _B_H
    #define _B_H
    
    extern "C" {
        #include "A.h"
    }
    
    #endif

这里A头文件和实现由C语言编写,而B模块则是C++编写。B的cpp文件无需做改动,只是在B.h中有处理。此外,由于extern "C"是C++的特性,因此可以利用C++定义的宏来判断是不是C++编译器编译。

#ifdef __cplusplus
extern "C" {
#endif

// 正式定义。。。

#ifdef __cplusplus

#endif

你可能感兴趣的:(学习记录,extern,"C",学习记录,使用)