前一篇文章介绍了如何在VS 2012下编译Lua源码,现在来做个小小的C++代码测试!
参考《Lua程序设计》一书写的一个小例子:
#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
int main()
{
char szBuffer[256];
int nError = 0;
lua_State* pLuaState = luaL_newstate(); //打开Lua
luaL_openlibs(pLuaState); /* 打开标准库 */
while (fgets(szBuffer, sizeof(szBuffer), stdin) != NULL)
{
nError = luaL_loadbuffer(pLuaState, szBuffer, strlen(szBuffer), "line") ||
lua_pcall(pLuaState, 0, 0, 0); /* 如果出错,会将错误信息压入栈 */
if (nError)
{
fprintf(stderr, "%s", lua_tostring(pLuaState, -1));
lua_pop(pLuaState, 1); /* 从栈中弹出错误信息 */
}
}
lua_close(pLuaState);
return 0;
}
在配置好头文件及库文件目录,以及添加Lua.lib库引用之后,编译,很不幸没有编译成功,错误信息如下:
1> luatest.cpp
1>luatest.obj : error LNK2019: 无法解析的外部符号 "void __cdecl lua_close(struct lua_State *)" (?lua_close@@YAXPAUlua_State@@@Z),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "void __cdecl lua_settop(struct lua_State *,int)" (?lua_settop@@YAXPAUlua_State@@H@Z),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "char const * __cdecl lua_tolstring(struct lua_State *,int,unsigned int *)" (?lua_tolstring@@YAPBDPAUlua_State@@HPAI@Z),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "int __cdecl lua_pcallk(struct lua_State *,int,int,int,int,int (__cdecl*)(struct lua_State *))" (?lua_pcallk@@YAHPAUlua_State@@HHHHP6AH0@Z@Z),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "int __cdecl luaL_loadbufferx(struct lua_State *,char const *,unsigned int,char const *,char const *)" (?luaL_loadbufferx@@YAHPAUlua_State@@PBDI11@Z),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "struct lua_State * __cdecl luaL_newstate(void)" (?luaL_newstate@@YAPAUlua_State@@XZ),该符号在函数 _main 中被引用
1>luatest.obj : error LNK2019: 无法解析的外部符号 "void __cdecl luaL_openlibs(struct lua_State *)" (?luaL_openlibs@@YAXPAUlua_State@@@Z),该符号在函数 _main 中被引用
1>F:\Test\Lua\LuaTest\Debug\LuaTest.exe : fatal error LNK1120: 7 个无法解析的外部命令
根据经验,这个肯定是库的问题,在经过仔细确认Lua.lib库引用正确之后,在网上搜索,折腾了很久也没有找到相关信息(可能是搜索关键词不对)。突然想到Lua解析器也是调用这些接口的,却可以编译成功。仔细对比了一下,发现唯一的区别就是实现代码的后缀不同,它的是.c,而我的是.cpp。尝试了一下将我的文件改为.c的,居然编译成功。这时才想到Lua源码文件中有一个专门针对C++的头文件:lua.hpp,文件内容如下:
// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
替换为
#include "lua.hpp"
此时,就可以顺利编译了!
这再一次提醒我:C写的函数要想在C++文件中调用,需要在函数前加extern "C".