最近在学Lua,关于Lua编译的地方,由于Lua是用C语言写的,在C++中使用C语言的函数,需要使用extern "C“编译才能过,之前貌似没有接触过这方面的知识,写个blog纪念一下,顺便整理一下extern关键字的作用。
error:预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
这是因为C语言和C++的预编译头不同,如果C语言文件较少,可以将C语言文件的属性->预编译头改为不使用预编译头,就可以解决问题啦。
而如果这时候直接在cpp文件中使用C语言的函数,则会出现下面的错误:
>C++Test.obj : error LNK2019: 无法解析的外部符号 "int __cdecl CTest(int,int)" (?CTest@@YAHHH@Z),该符号在函数 _wmain 中被引用。
错误发生在link阶段,连接器没有找到int_cdecl CTest(int int)这个函数,而我们明明写了CTest这个函数。原因是C++和C的编译方式不同,C++支持函数重载,所以在编译的时候,函数名称后面通常会加上一大堆奇葩的东东,一般是记录重载的信息的,具体被编译成什么样需要看编译器的脾气。而C语言不支持重载,所以编译得比较”纯净“,而我们按照C++的编译方式去编译了一个C语言的函数,就会造成上面的错误。
在编译的时候,如果要包含C语言的东东,在C语言的头文件上下加上extern"C"就可以解决这个问题。
注:在C语言中不支持extern "C"这个关键字组合,所以要加上这一句话的话需要在C++引入C语言的头文件的部分来添加这个。如果在C语言中添加的话,会出现下面的错误:
error C2059: 语法错误:“字符串”
看一个C++混合编译C语言函数的例子:
C语言头文件:
#ifndef __CFILE_H_
#define __CFILE_H_
int CTest(int a, int b);
#endif
C语言实现文件:
#include "CFile.h"
int CTest(int a, int b)
{
return a + b;
}
C++文件:
// C++Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
using namespace std;
//使用extern "C"关键字,声明这个东东是C语言的,不要用C++的方式来
// __cplusplus是cpp文件内置的宏,作用为如果是cpp文件,才进行相关编译。这样写更好地控制了编译流。
#ifdef __cplusplus
extern "C"{
#endif
#include "CFile.h"
#ifdef __cplusplus
};
#endif
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1;
int b = 2;
cout<
这样写的话,再编译就可以通过啦!
运行结果如下:
3
请按任意键继续. . .
关于extern "C"要注意的地方:
1.在使用C语言写的lib或者dll时,包含的.h头需要写在extern "C"{//头文件}之中。
2.在C语言的文件中不要这么写,因为C语言不支持extern ”C“关键字。
3.在cpp文件中使用ifdef __cplusplus控制编译流,如果是cpp文件,才进行相关的编译操作。
关于extern "C"的解释有两篇文章讲的很详细:
http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html
http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html
#ifndef __STATIC_TEST_H_
#define __STATIC_TEST_H_
//声明变量(加上extern关键字,说明在此处只是声明,定义在其他文件中)
extern int num;
//声明函数
void TestFunc();
#endif
#include "stdafx.h"
#include
#include "StaticTest.h"
using namespace std;
//定义变量
int num = 10;
//定义函数
void TestFunc()
{
cout<
// C++Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
//引用了StaticTest.h文件,将num的声明包含进来,所以在此文件中可以直接使用num变量和TestFunc函数了
#include "StaticTest.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
TestFunc();
cout<