最近在学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 <iostream> 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<<CTest(a, b)<<endl; system("pause"); return 0; }这样写的话,再编译就可以通过啦!
运行结果如下:
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 <iostream> #include "StaticTest.h" using namespace std; //定义变量 int num = 10; //定义函数 void TestFunc() { cout<<num<<endl; }
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> //引用了StaticTest.h文件,将num的声明包含进来,所以在此文件中可以直接使用num变量和TestFunc函数了 #include "StaticTest.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { TestFunc(); cout<<num<<endl; system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/puppet_master/article/details/47681849