extern "C"的作用

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

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

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

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

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

//a minimum program to test why extern "C" is need in C++
#include<stdio.h> namespace myname {
int var = ;
} extern "C" int _ZN6myname3varE; int main()
{
printf("%d\n", _ZN6myname3varE);
myname::var ++;
printf("%d\n", _ZN6myname3varE); printf("%p\n",&_ZN6myname3varE);
printf("%p\n", &myname::var);
return ;
}

编译执行结果:

$:~/blog/lua$ g++ extern_c.cc
$:~/blog/lua$ ./a.out 0x601040
0x601040

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

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

#ifdef __cplusplus
extern "C" {
#endif // 正式定义。。。 #ifdef __cplusplus
}
#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. 20175236 2018-2019-2 《Java程序设计》第七周学习总结

    教材学习内容总结 String类 String类在java.lang包中的类被默认引入,因此程序可以直接使用String类 Java把String类定义为final类,因此用户不能扩展String类, ...

  2. Linux系统编程——水平触发和边沿触发

    事件模型 EPOLL事件有两种模型: Edge Triggered (ET) 边缘触发只有数据到来才触发,不管缓存区中是否还有数据. Level Triggered (LT) 水平触发只要有数据都会触 ...

  3. Unity暂停游戏功能

    关于暂停游戏功能的做法,网上的教程以及Unity官方发布的Demo都是通过把Time.timeScale设成0来实现的,然而这会导致一些蛋疼的问题,因为Time.timeScale是全局变量,改成0后 ...

  4. sql脚本过大,无法打开的解决方法

    打开cmd命令窗口,输入如下命令: sqlcmd -S ipaddress -U user -P password -d dbname -i file 其中,ipaddress是数据库服务器ip,us ...

  5. C# HtmlAgilityPack 爬虫框架

    这两天公司不是很忙,在某个网站看见别人爬虫出来的数据感觉很有兴趣就玩了一把,网上找了一个 HtmlAgilityPack 爬虫框架,用了一下感觉很不错 首先从Nuget上面更新Package:Html ...

  6. java实现字符串和LIST,MAP转换

    需要下载第三方的jar :net.sf.json import java.io.BufferedReader; import java.io.InputStream; import java.io.I ...

  7. BATCH、事务、CLOB、BLOB

    Batch:需要执行大量的数据时可以使用批处理 注意点: 1.尽量使用Statement,因为如果是PreParedStatement可能会因为数据量太大而存在空间问题,编译器会报错. 2.把自动提交 ...

  8. JVM运行、类加载的全过程

    类加载机制:JVM把CLASS文件加载到内存,并对数据进行校验.解析和初始化,最终形成JVM可以直接使用的Java文件. 加载:把class文件字节码加载到内存中,并且将这些静态数据转换成方法区中的运 ...

  9. gp工具的许可

    还是要在代码里许可 static class Program { [STAThread] static void Main() { ESRI.ArcGIS.RuntimeManager.Bind(ES ...

  10. lambda函数式编程

    一.接口注解(@FunctionalInterface) @FunctionalInterface interface Interface1 { public void print(); } publ ...