extern "C"的作用

在C++引用lua的头文件时,我们总会写成:

  1. extern "C" {
  2. #include "lua.h"
  3. #include "lualib.h"
  4. #include "lauxlib.h"
  5. }

为什么要这么做呢?原因是C++的编译器会对程序中符号进行修饰,这个过程在编译器中叫符号修饰(Name Decoration)或者符号改编(Name Mangling)。

同时我们知道C++是能够兼容C的,如果我们有了一个C语言的头文件和其对于的库,在C++中如何使用它呢?在include该头文件的时候当然要加入extern "C",否则按照C++的符号进行符号修饰,那么在库中就会找不到该符号了。

为了加深印象,再看一个例子:

  1. //a minimum program to test why extern "C" is need in C++
  2. #include<stdio.h>
  3.  
  4. namespace myname {
  5. int var = ;
  6. }
  7.  
  8. extern "C" int _ZN6myname3varE;
  9.  
  10. int main()
  11. {
  12. printf("%d\n", _ZN6myname3varE);
  13. myname::var ++;
  14. printf("%d\n", _ZN6myname3varE);
  15.  
  16. printf("%p\n",&_ZN6myname3varE);
  17. printf("%p\n", &myname::var);
  18. return ;
  19. }

编译执行结果:

  1. $:~/blog/lua$ g++ extern_c.cc
  2. $:~/blog/lua$ ./a.out
  3.  
  4. 0x601040
  5. 0x601040

在这个例子中,我们根据g++编译器的符号修饰规则,仿造了一个C变量(gcc不进行符号修饰),欺骗了编译器,把myname::var 和 _ZN6myname3varE当成了同一个变量了。

还有另外一个问题,C语言不支持extern "C"语法,如果我们想写一个头文件,同时支持被C和C++引用,该怎么办?可以使用C++的宏 "__cplusplus"来判断是不是C++编译器。

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4.  
  5. // 正式定义。。。
  6.  
  7. #ifdef __cplusplus
  8. }
  9. #endif

C++中为什么有时要使用extern "C"的更多相关文章

  1. 单片机项目开发中的Muliple Inialliaztion和Mutilple Definition解决:在.c中定义全局变量或者用extern加以声明

    c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下.      对于比较小的程序,一般只有一个c文件和一个头文件 ...

  2. C# 中[DllImport("user32.dll")]和extern用法和示例----转载

    原文:https://blog.csdn.net/michellehsiao/article/details/7629746         extern 修饰符用于声明在外部实现的方法.extern ...

  3. 在 C# CLR 中学习 C++ 之了解 extern

    一:背景 在 CLR 源码中有很多的 extern 和 extern "C" 这样的关键词,比如下面这些代码: extern size_t gc_global_mechanisms ...

  4. 转:C++项目中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __c ...

  5. C++项目中的extern "C" {}

    from:http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html C++项目中的extern "C" {} 20 ...

  6. OC中的extern,static,const

    const的作用: const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p). 被const修饰的变量是只读的. static的作用: 修饰局部变量: 1.延长局部变量的生命周期,程序结束才会 ...

  7. C/C++:C++中static,extern和extern "C"关键字

    1. extern 变量 extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量. 当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern in ...

  8. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  9. C++中extern关键字用法小结

    总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...

随机推荐

  1. 报错:Failed on local exception: Host Details : local host is: "master/192.168.52.26"; dest

    报错现象 Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Protocol message ...

  2. [转]Win2012的 IIS 503 错误

    下载并安装 https://www.microsoft.com/zh-CN/download/details.aspx?id=48145 因为安装了 dotnet-hosting-2.2.3-win. ...

  3. bitmap--Bitmap详解与Bitmap的内存优化

    一.Bitmap: Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图像剪切.旋转.缩放等操作,并可以指定格式保存图像文件. 常用方法: public voi ...

  4. Notification之适配总结

    11. android通知栏8.0系统报错误: NotificationService: No Channel found for pkg=xxx.xxx.xxx, channelId=12345, ...

  5. iOS设置截图背景图片透明

    /** 设置图片背景为透明 */- (UIImage *)imageToTransparent { // 分配内存 const int imageWidth = self.size.width; co ...

  6. Linux下基础查看命令

    1:查看系统32位还是64位,如下三种方法       uname -m        uname -a        ls -ld  /lib64 2:查看系统版本   cat /etc/redha ...

  7. 易酷 cms2.5 本地文件包含漏洞 getshell

    易酷 cms2.5  本地文件包含漏洞 getshell 首先下载源码安装(http://127.0.0.1/test/ekucms2.5/install.php) 安装成功直接进行复现吧 本地包含一 ...

  8. CDNI - RFC 6707 翻译

    CDNI的相关问题陈述 概述 CDN对可缓存内容提供了许多好处:降低交付成本,提高终端用户体验,提高交付的鲁棒性.对于这些因素,CDN常 用于大规模的内容交付.因此,现有的CDN提供商正在扩大规模,许 ...

  9. Java 中 Equals和==的区别(转)

    另外一篇参考: https://blog.csdn.net/striverli/article/details/52997927 在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的 ...

  10. python 常用技巧

    一.字符串与数值的转换 Python中字符串转换为数值: str_num = '99' num = int(str_num) 整型数转换为字符串: num = 99 str_num = str(num ...