关于extern “C“ {} 的理解

我们经常在代码中看到这样的声明:

#ifdef __cplusplus
    extern "C" {
    #endif

 .........

#ifdef __cplusplus
  }
#endif

其中#ifdef __cplusplus是用来判断文件是否为cpp文件,这个很好理解,那被它限定的extern “C” { }又是什么意思呢?其实这个extern “C” { }就是表达了两个含义

(1)extern表示{ }内声明的函数和变量是外部变量和函数(见注释1);

(2)“C”表示{ }内的函数都是以C语言的形式编译的,告诉编译器要以C语言形式对{}的函数进行编译(对实现文件来说)或者以C语言的形式查找函数(对引用这些函数的文件来说)。

我们知道编译器对C和C++文件定义的函数在编译时会按照一定规则来记录函数的名字,由于C++允许重载,所以编译后的函数名中一般会加上函数的参数类型用以区分不同的重载函数。而C没有这样的特性,这就造成了两种文件编译后的函数名字不同,为了防止多人协作中出现C、C++语言的不同造成的兼容问题,一般要在函数的声明处加上extern “C” { 函数声明}来限定它用C语言编写, 总之,函数的实现方式一定要和函数的查找方式一致,是C都是C,C++就都是C++,以下是几种使用情况说明:

(1)一个程序中有三个文件:main.cpp, func.h, func.cpp, func.h中用extern “C” { }限定了所有function,则在main和func.cpp中无论怎么引用func.h都可以,加不加extern “C” { }都行,func.cpp会以C形式编译

(2)main.cpp, func.h, func.cpp,三个文件都没有用extern “C” { }限定,编译运行都没有问题,因为function的编译和main都是C++形式的,main中查找function是用C++形式查找的,没有问题

(3)main.c, func.h, func.cpp, 这种情况必须在func.h中加extern “C” { }, 或者在func.cpp引用func.h的地方把func.h用extern “C” {}包起来,

extern "C" {
    #include "PCMFunc.h"
    }

(4)main.cpp, func.h, func.c,这种情况必须在main.cpp中引用func.h是用extern “C” {}把func.h包起来

 extern "C" {
    #include "PCMFunc.h"
    }

最后请注意这样书写

extern "C" {
#include "PCMFunc.h"
}

不要这样写

extern "C" {#include "PCMFunc.h"}

注释1:所谓外部函数和变量也就是全局函数和变量,是在整个程序的各个文件和so库中的API都可见的函数和变量,比如在1.so中引用一个头文件,头文件声明一个外部全局函数extern void func(); 在主程序中同样引用这个头文件并在主程序的某个cpp文件中实现它,那么在运行过程中,1.so是可以找到并调用这个func()的。相反,在so中实现一个extern 函数并声明导出(用.def文件),在主程序中加载声明的头文件并引用链接这个so,在主程序中照样能调用这个extern 函数。extern变量也是这样。

注释2,在所有函数外部声明一个函数或变量后,不加关键字extern时一般默认为全局,想要声明成本地函数和变量,则必须加static关键字限定为只在本文件内可见。
关于注释2需要注意的几点:
(1)全局变量指的是其生命周期是在整个程序运行的完整周期内的,并不是指这个变量定义好了之后就在各处都可见了,它仍然需要严格遵循作用域规则。例如在main函数之后定义一个变量

 int main(void)
    {}
    int g_num = 11;

此时想要在main中使用这个g_num是不行的,因为不在它的作用域, 需要在使用之前增加 extern int g_num;或者int g_num; 这样的声明。
(2)定义在函数之后的全局变量即使在函数内用extern声明,其作用域也并不是全局的,所以它不属于global namespac的成员,不能使用全局作用域运算符::来调用它,除非它的声明或定义在main函数之上(可以在其他函数的定义或声明之后,大家都是全局的)。

注释3:extern “C++” { }也是存在的哦

extern "C++" {
    ... ...
}
  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,extern关键字用于声明变量或函数的定义在其他文件中。它的作用是告诉编译器在遇到该变量或函数时,在其他模块中寻找其定义。另外,extern还可以用来进行链接指定。 在使用extern关键字时,需要注意以下几点: 1. 在一个源文件中定义了一个数组char a,在另外一个文件中使用extern char *a进行声明,这是不合法的。因为指向类型T的指针与类型T的数组并不等价。应该将声明改为extern char a[]。这样才能正确访问数组元素。 2. extern关键字常常用于变量声明中,当在.c文件中声明了一个全局变量,并且要被其他文件引用时,需要将其放在头文件中,并使用extern进行声明。这样可以确保其他文件能正确访问该变量。 3. 当C语言调用一个由C语言编写的动态链接库(DLL)时,在包括DLL的头文件或声明接口函数时,应该加上extern "C" {}。这是为了确保C语言能够正确引用DLL中的函数和变量。 总结来说,extern关键字在C语言中的使用常见于实现C与C及其他语言的混合编程。它能够帮助我们引用其他文件的函数和变量,并确保链接的正确性。在使用extern时需要注意格式的严格对应,以避免出现运行时错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [深入理解C语言之extern](https://blog.csdn.net/shenwanjiang111/article/details/52912753)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值