首先说一下一个问题,这个问题困惑了我很久,为什么调用Lua的函数时,对其头文件要加extern "C"的声明?
形如:
extern "C" { //指定这些都是用C语言编译的
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
问题:C++去调用C语言编译后生成的动态库文件,为什么要加extern "C"?
首先,我们要知道一点,C++是支持重载的,而C语言并不支持这一功能
由于C++支持重载,所以同名的函数,在底层生成的名字都不一样
例如:void Add(int, int)函数
C++在底部可能生成的是__Add_int_int
而C在底部生成的则是__Add
所以,C语言编译的动态库去给C++调用,会出现这样的问题:(继续拿void Add(int int)做例子)
C++在底层去寻找的是__Add_int_int这个函数原型
而真实的确实C语言提供的函数原型_Add
这样C++调用时会报错说找不到这个函数,这是由于C++和C语言的命名规则不一样导致的
所以为了兼容C语言,或者说为了C和C++能完美兼容,有了extern "C"的诞生
当我们在C++中调用C语言编译后的函数,我们在其.h的头文件声明加上extern "C"的字眼,告诉编译器,请您按照C的方式去解析这些函数
实例:
extern "C" void Add(int , int); //用C编译器编译过的函数
或者
extern "C" { //表明这些头文件的内容都是用C语言编译过的
#include "func1.h"
#include "func2.h"
}
这也完美解释了Lua(我们得知道Lua工程都是用C写的)为什么用C++调用得加extern "C"
在最后我再推荐一款查看.dll文件内容的软件Dependency Walker,让大家看的更加清晰
同样的程序.cpp文件和.c文件生成的动态库内容:
.h的头文件内容:
.CPP
.C