您的位置:首页 > 编程语言 > Lua

创建一个调用lua方法的C++工程

2015-03-27 20:40 417 查看
这里想要吐槽一下最近用来学习Lua的书籍《XX开发实践指南》(虽然没有写全名不过搜索过Lua学习资料的童鞋应该都懂是哪本书),不知道是作者问题还是译者问题,有些地方的解释说明有点糟糕,要么不够详细要么词不达意。嘛,吐槽完了还是要感谢一下作者和译者的辛苦成果。

一、准备工作

1、下载Lua源码。

2、将源码放在合适的盘(我的在D盘,路径D:/Lua-5.2.3/src)

3、打开vs2013新建一个win32控制台应用程序(Win32 console project ),我将他取名为LuaLib


4、确定后,会弹出应用程序向导的提示框,点击下一步。应用程序类型选择静态库(static Library),附加选项去掉预编译头(Precomplied Header ),点击完成。



5、向工程中添加头文件(.h)与源码(.c)

1)将D:/lua-5.2.3/src中所有.h文件复制到头文件(Header Files)中

2)将D:/lua-5.2.3/src中所有.c文件复制到源文件(Code Files)中

6、配置项目属性,打开项目->属性->配置属性

1)在C/C++项中点开常规,第一项附加包含目录中填上D:/lua-5.2.3/src

2)在C/C++项中点开高级,第二项编译为选择编译为C代码(/TC)





7、生成项目,生成成功后会Debug(Release)文件中生成lua.lib文件。在这里我生成时报了错:

error c4996: 'fopen': This function or variable may be unsafe

若出现这个错误,需要在属性页的预处理器定义中加入_CRT_SECURE_NO_WARNINGS,再次生成就可以了。


二、在C++代码中调用Lua

1、新建win32控制台应用程序,取名为TestLua,后面的不用改

2、在该项目的通用属性中添加Lualib的引用



//test.cpp

#include "stdafx.h"
#include <string>
#include <iostream>

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

using namespace std;

lua_State* L;
int _tmain(int argc, _TCHAR* argv[])
{
//初始化lua
L = luaL_newstate();
luaL_openlibs(L);
//加载lua脚本, 脚本放在工程目录下
luaL_loadfile(L, "testA.lua");
int dwError = lua_pcall(L, 0 ,LUA_MULTRET,0);
if(dwError != 0)
{
cout<<lua_tostring(L,-1);
lua_close(L);
return 1;
}

//调用 lua中的函数
int a = 10;
int b = 11;
lua_getglobal(L,"SumFunc");
lua_pushinteger(L,a);
lua_pushinteger(L,b);
int dwRet = lua_pcall(L,2,1,0);
if(dwRet != 0)
{
cout<<lua_tostring(L, -1);
lua_pop(L,1);
return 0;
}
printf("sum: %d + %d = %ld\n", a,b,lua_tointeger(L,-1));
lua_pop(L,-1);

//调用结束,清除Lua
lua_close(L);
return 0;
}


//test.lua

function SumFunc( a, b)

return a + b;

end

//test.lua end

很简单的程序,注意以下两个函数

注:luaL_loadfile 和 luaL_dofile 的区别!!!!!具体的我还要查API.

3、在C
C和lua相互调用的例子(来自网络)

//test.c

[cpp] view
plaincopy

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

//lua头文件

#include <lua.h>

#include <lualib.h>

#include <lauxlib.h>

#define err_exit(num,fmt,args) \

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);exit(num);} while(0)

#define err_return(num,fmt,args) \

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);return(num);} while(0)

//lua中调用的c函数定义,实现加法

int csum(lua_State* l)

{

int a = lua_tointeger(l,1) ;

int b = lua_tointeger(l,2) ;

lua_pushinteger(l,a+b) ;

return 1 ;

}

int main(int argc,char** argv)

{

lua_State * l = luaL_newstate() ; //创建lua运行环境

if ( l == NULL ) err_return(-1,"luaL_newstat() failed");

int ret = 0 ;

ret = luaL_loadfile(l,"func.lua") ; //加载lua脚本文件

if ( ret != 0 ) err_return(-1,"luaL_loadfile failed") ;

ret = lua_pcall(l,0,0,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

lua_getglobal(l,"width"); //获取lua中定义的变量

lua_getglobal(l,"height");

printf("height:%ld width:%ld\n",lua_tointeger(l,-1),lua_tointeger(l,-2)) ;

lua_pop(l,1) ; //恢复lua的栈

int a = 11 ;

int b = 12 ;

lua_getglobal(l,"sum"); //调用lua中的函数sum

lua_pushinteger(l,a) ;

lua_pushinteger(l,b) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("sum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1)) ;

lua_pop(l,1) ;

const char str1[] = "hello" ;

const char str2[] = "world" ;

lua_getglobal(l,"mystrcat"); //调用lua中的函数mystrcat

lua_pushstring(l,str1) ;

lua_pushstring(l,str2) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("mystrcat:%s%s = %s\n",str1,str2,lua_tostring(l,-1)) ;

lua_pop(l,1) ;

lua_pushcfunction(l,csum) ; //注册在lua中使用的c函数

lua_setglobal(l,"csum") ; //绑定到lua中的名字csum

lua_getglobal(l,"mysum"); //调用lua中的mysum函数,该函数调用本程序中定义的csum函数实现加法

lua_pushinteger(l,a) ;

lua_pushinteger(l,b) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("mysum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1)) ;

lua_pop(l,1) ;

lua_close(l) ; //释放lua运行环境

return 0 ;

}

//test.lua end

很简单的程序,注意以下两个函数

int luaL_dofile (lua_State *L, const char *filename)和int luaL_loadfile (lua_State *L, const char *filename);

luaL_dofile在源码中的定义如下:

#define luaL_dofile(L, fn) \

(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))

所以,如果调用luaL_loadfile 加载lua脚本文件,则不需要再次调用lua_pcall(L, 0, 0, 0);如果是调用luaL_dofile加载,则需要在程序中调用一次lua_pcall(L, 0, 0, 0);

C和lua相互调用的例子(来自网络)

//test.c

[cpp] view
plaincopy

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

//lua头文件

#include <lua.h>

#include <lualib.h>

#include <lauxlib.h>

#define err_exit(num,fmt,args) \

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);exit(num);} while(0)

#define err_return(num,fmt,args) \

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);return(num);} while(0)

//lua中调用的c函数定义,实现加法

int csum(lua_State* l)

{

int a = lua_tointeger(l,1) ;

int b = lua_tointeger(l,2) ;

lua_pushinteger(l,a+b) ;

return 1 ;

}

int main(int argc,char** argv)

{

lua_State * l = luaL_newstate() ; //创建lua运行环境

if ( l == NULL ) err_return(-1,"luaL_newstat() failed");

int ret = 0 ;

ret = luaL_loadfile(l,"func.lua") ; //加载lua脚本文件

if ( ret != 0 ) err_return(-1,"luaL_loadfile failed") ;

ret = lua_pcall(l,0,0,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

lua_getglobal(l,"width"); //获取lua中定义的变量

lua_getglobal(l,"height");

printf("height:%ld width:%ld\n",lua_tointeger(l,-1),lua_tointeger(l,-2)) ;

lua_pop(l,1) ; //恢复lua的栈

int a = 11 ;

int b = 12 ;

lua_getglobal(l,"sum"); //调用lua中的函数sum

lua_pushinteger(l,a) ;

lua_pushinteger(l,b) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("sum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1)) ;

lua_pop(l,1) ;

const char str1[] = "hello" ;

const char str2[] = "world" ;

lua_getglobal(l,"mystrcat"); //调用lua中的函数mystrcat

lua_pushstring(l,str1) ;

lua_pushstring(l,str2) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("mystrcat:%s%s = %s\n",str1,str2,lua_tostring(l,-1)) ;

lua_pop(l,1) ;

lua_pushcfunction(l,csum) ; //注册在lua中使用的c函数

lua_setglobal(l,"csum") ; //绑定到lua中的名字csum

lua_getglobal(l,"mysum"); //调用lua中的mysum函数,该函数调用本程序中定义的csum函数实现加法

lua_pushinteger(l,a) ;

lua_pushinteger(l,b) ;

ret = lua_pcall(l,2,1,0) ;

if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

printf("mysum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1)) ;

lua_pop(l,1) ;

lua_close(l) ; //释放lua运行环境

return 0 ;

}

//end test.c

//func.lua

[python] view
plaincopy

--变量定义

width=1 ;

height=2 ;

--lua函数定义,实现加法

function sum(a,b)

return a+b ;

end

--lua函数定义,实现字符串相加

function mystrcat(a,b)

return a..b ;

end

--lua函数定义,通过调用c代码中的csum函数实现加法

function mysum(a,b)

return csum(a,b) ;

end

//end func.lua
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐