c++和lua

原帖地址:
http://www.cnblogs.com/sevenyuan/p/4511808.html

lua和c++的交互就是通过一个无处不在的栈来实现的,此图如此传神啊!
这里写图片描述

#include <iostream>  
#include <string.h>  
using namespace std;  

extern "C"  
{  
    #include "lua.h"  
    #include "lauxlib.h"  
    #include "lualib.h"  
}  
void main()  
{  
    //1.创建一个state  
    lua_State *L = luaL_newstate();  

    //2.入栈操作  
    lua_pushstring(L, "I am so cool~");   
    lua_pushnumber(L,20);  

    //3.取值操作  
    if( lua_isstring(L,1)){             //判断是否可以转为string  
        cout<<lua_tostring(L,1)<<endl;  //转为string并返回  
    }  
    if( lua_isnumber(L,2)){  
        cout<<lua_tonumber(L,2)<<endl;  
    }  

    //4.关闭state  
    lua_close(L);  
    return ;  
}

我们可以用push*的方式将我们的数据,或者说是c++中的数据送到栈里面去。在上面的示例中,我们push了两个数据到lua的栈里面去,一个string = “I am so cool”,另一个是一个数字“20”。然后我们用lua_is*将这些数据取出来,并切输出到显示器。
不过在进行所有的这些操作之前,我们必须要手动建立一个lua栈,这是通过lua_newstate()完成的。这个函数返回指向这个栈栈顶的指针。

示例:如何读取lua中的数据到cpp中来,只要完成了这个,就可以用lua做我们的配置文件了,感觉比xml什么的牛多了。
这是我们的lua代码,里面存储了一些数据,如下:

str = "I am so cool"  
tbl = {name = "shun", id = 20114442}  
function add(a,b)  
    return a + b  
end

读取这个lua文件中的数据的c++代码如下:

#include <iostream>  
#include <string.h>  
using namespace std;  

extern "C"  
{  
    #include "lua.h"  
    #include "lauxlib.h"  
    #include "lualib.h"  
}  
void main()  
{  
    //1.创建Lua状态  
    lua_State *L = luaL_newstate();  
    if (L == NULL)  
    {  
        return ;  
    }  

    //2.加载Lua文件  
    int bRet = luaL_loadfile(L,"hello.lua");  
    if(bRet)  
    {  
        cout<<"load file error"<<endl;  
        return ;  
    }  

    //3.运行Lua文件  
    bRet = lua_pcall(L,0,0,0);  
    if(bRet)  
    {  
        cout<<"pcall error"<<endl;  
        return ;  
    }  

    //4.读取变量  
    lua_getglobal(L,"str");  
    string str = lua_tostring(L,-1);  
    cout<<"str = "<<str.c_str()<<endl;        //str = I am so cool~  

    //5.读取table  
    lua_getglobal(L,"tbl");   
    lua_getfield(L,-1,"name");  
    str = lua_tostring(L,-1);  
    cout<<"tbl:name = "<<str.c_str()<<endl; //tbl:name = shun  

    //6.读取函数  
    lua_getglobal(L, "add");        // 获取函数,压入栈中  
    lua_pushnumber(L, 10);          // 压入第一个参数  
    lua_pushnumber(L, 20);          // 压入第二个参数  
    int iRet= lua_pcall(L, 2, 1, 0);// 调用函数,调用完成以后,会将返回值压入栈中,2表示参数个数,1表示返回结果个数。  
    if (iRet)                       // 调用出错  
    {  
        const char *pErrorMsg = lua_tostring(L, -1);  
        cout << pErrorMsg << endl;  
        lua_close(L);  
        return ;  
    }  
    if (lua_isnumber(L, -1))        //取值输出  
    {  
        double fValue = lua_tonumber(L, -1);  
        cout << "Result is " << fValue << endl;  
    }  

    //至此,栈中的情况是:  
    //=================== 栈顶 ===================   
    //  索引  类型      值  
    //   4   int:      30   
    //   3   string:   shun   
    //   2   table:     tbl  
    //   1   string:    I am so cool~  
    //=================== 栈底 ===================   

    //7.关闭state  
    lua_close(L);  
    return ;  
}

如果这些代码出现链接错误,说明没有配置好lua的lib和dll文件的位置。
我们可以通过调用lua_pcall(L,0,0,0)来清空lua的堆栈。

获取lua错误堆栈中的信息:

原帖地址:
http://www.cnblogs.com/meteoric_cry/p/3665258.html

lua_getglobal(tolua_S, "debug"); 
lua_getfield(tolua_S, -1, "traceback"); 
int iError = lua_pcall( tolua_S,//VMachine 
0,//Argument Count 
1,//Return Value Count 
0); 
const char* sz = lua_tostring(tolua_S, -1); 

CCLog(sz); 

在lua中用c++的函数

原帖地址:
http://www.cnblogs.com/Zackzhang/p/5094942.html
在lua中调用c++的函数有两种方法,一是将c函数作为应用程序的一部分,二是将c函数作为lua的一个模块。
怎么理解第一种方式呢?我们的c代码里是有main函数的,我们将我们需要在lua中调用的函数在main函数里注册一下,然后在lua里直接调用。第二种方式是将我们的函数弄到一个dll里面(windows平台是dll,unix中是so),然后通过lua的require关键字把这个dll作为一个模块包含进来,然后就可以愉快的使用c++中的函数了。
在lua中调用c函数,那么c函数需要的参数自然就是从lua中传过去的了。
上代码:

#include <stdio.h>
#include <string.h>
#include "lua.hpp"
#include "lauxlib.h"
#include "lualib.h"

//待注册的函数
//该函数必须以c的形式被导出,因此extern "C"是必须的

extern "C" int average(lua_State* L)
{
    double sum = 0;
    int num = lua_gettop(L);//获取参数的个数,因为栈顶的正数代表的正是参数的个数
    for (int i = 1; i <= num; i++)
    {
        sum += lua_tonumber(L, i);//将栈中的元素挨个取出并相加
    }
    //在上面的过程执行之后,我们将平均值入栈,作为返回值
    lua_pushnumber(L, sum / num);

    return 1;//返回返回值的个数,通知lua应该从栈里面取几个值作为返回结果,因为lua是支持多重返回值的
}

extern "C" int Communicate(lua_State* L)
{
    const char* name = lua_tostring(L, 1);//从lua中获取字符串
    printf("Hello %s\n", name);
    printf("I'm in C,I send a message to you");
    lua_pushstring(L, "this message from C");

    return 1;
}

//luaL_Reg结构体的第一个字段为字符串,在注册时用于通知Lua该函数的名字。
//第一个字段为C函数指针。
//结构体数组中的最后一个元素的两个字段均为NULL,用于提示Lua注册函数已经到达数组的末尾。

static luaL_Reg cMethods[] = {
    {"average",average},
    {"Communicate ",Communicate },
    {NULL,NULL}
};

//该C库的唯一入口函数。其函数签名等同于上面的注册函数。见如下几点说明:
//1. 我们可以将该函数简单的理解为模块的工厂函数。
//2. 其函数名必须为luaopen_xxx,其中xxx表示library名称。Lua代码require "xxx"需要与之对应。
//3. 在luaL_register的调用中,其第一个字符串参数为模块名"xxx",第二个参数为待注册函数的数组。
//4. 需要强调的是,所有需要用到"xxx"的代码,不论C还是Lua,都必须保持一致,这是Lua的约定,
//   否则将无法调用。

extern "C" __declspec(dllexport)
int luaopen_Mydll(lua_State* L)
{
    const char* libName = "Mydll";
    luaL_register(L, libName, cMethods);
    return 1;
}

按下vs中的F7执行编译,然后就可以得到我们要用的dll了。
这里写图片描述

hello.lua的写法

require "Mydll"  --引入包

 --在调用时,必须是package.function

print(Mydll.average(1.0,2.0,3.0,4));
print(Mydll.Communicate("Zack"));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值