现在的位置: 首页 > 综合 > 正文

第一章 lua与c++的互调

2014年04月05日 ⁄ 综合 ⁄ 共 2695字 ⁄ 字号 评论关闭

Sample.lua内容

function func_Add(x, y)
   return x+y
end

avg, sum = c_average(10, 20, 30, 40, 50)

lua调用C++

      在lua中是以函数指针的形式调用函数, 并且所有的函数指针都必须满足如下此种类型:
typedef int (*lua_CFunction) (lua_State *L);  
也就是说, 偶们在C++中定义函数时必须以lua_State为参数, 以int为返回值才能被Lua所调用. 但是不要忘记了, 偶们的lua_State是支持栈的, 所以通过栈可以传递无穷个参数, 大小只受内存大小限制. 而返回的int值也只是指返回值的个数真正的返回值都存储在
lua_State的栈中. 偶们通常的做法是做一个wrapper, 把所有需要调用的函数都wrap一下, 这样就可以调用任意的函数了.

// LuaTest.cpp : 定义控制台应用程序的入口点。

#include<iostream>  
using namespace std; 

extern "C" 

#include "lua.h"  
#include "lualib.h"  
#include "lauxlib.h"  
}; 

#pragma comment(lib, "LuaLib.lib")  

lua_State* m_pState; 

// c+++调用LUA
int lua_add(const char* pFunctionName, int nParam1, int nParam2)
{
 int nRet = 0;
 if(NULL == m_pState)
 {
  printf("[CLua::CallFileFn]m_pState is NULL./n");
  return 0;
 }

 lua_getglobal(m_pState, pFunctionName);

 lua_pushnumber(m_pState, nParam1);
 lua_pushnumber(m_pState, nParam2);

 //lua_gettop()这个API是告诉你目前栈里元素的个数。
 int nIn = lua_gettop(m_pState);
 
 nRet = lua_pcall(m_pState, 2, 1, 0);
 if (nRet != 0)
 {
  printf("[CLua::CallFileFn]call function(%s) error(%d)./n", pFunctionName, nRet);
  return 0;
 }

 if (lua_isnumber(m_pState, -1) == 1)
 {
  int nSum = lua_tonumber(m_pState, -1);
  printf("[CLua::CallFileFn]Sum = %d./n", nSum);
  lua_pop(m_pState, -1);
 }

 return 1;
};

// lua调用C++
static int c_average(lua_State *m_pState) 

    //返回栈中元素的个数 
    int n = lua_gettop(m_pState);

    double sum = 0; 

    for (int i = 1; i <= n; i++) 
    { 
        if (!lua_isnumber(m_pState, i))  
        { 
            lua_pushstring(m_pState, "Incorrect argument to 'average'"); 
            lua_error(m_pState); 
        }

        sum += lua_tonumber(m_pState, i); 
    } 

    // push the average
    lua_pushnumber(m_pState, sum / n); 

    //push the sum  
    lua_pushnumber(m_pState, sum); 
     
    /* return the number of results */ 
    return 2; 

void Lua_Call_C()
{
 /* initialize Lua */ 
 m_pState = luaL_newstate(); 
 /* load Lua libraries */ 
 luaL_openlibs(m_pState); 
 /* register our function */ 
 lua_register(m_pState, "c_average", c_average); 
 /* run the script */ 
 luaL_dofile(m_pState, "E:\\cocos2d\\LuaProject\\LuaLib\\Debug\\Sample.lua"); 
  
 lua_getglobal(m_pState,"avg"); 
 cout<<"avg is:"<<lua_tointeger(m_pState,-1)<<endl; 
 lua_pop(m_pState,1); 
 lua_getglobal(m_pState,"sum"); 
 cout<<"sum is:"<<lua_tointeger(m_pState,-1)<<endl; 
 /* cleanup Lua */ 
 lua_close(m_pState); 
}

void C_Call_Lua()
{
 int sum = 0; 
 m_pState = luaL_newstate(); 
 luaopen_base(m_pState); 
 luaL_dofile(m_pState, "E:\\cocos2d\\LuaProject\\LuaLib\\Debug\\Sample.lua"); 
 sum = lua_add("func_Add",10, 5); 
 cout<<"Sum = "<<sum<<endl;         
 lua_close(m_pState); 
}

//栈
//当你初始化一个栈的时候,它的栈底是1,而栈顶相对位置是-1,
//说形象一些,你可以把栈想象成一个环,有一个指针标记当前位置,
//如果-1,就是当前栈顶,如果是-2就是当前栈顶前面一个参数的位置。
//以此类推。当然,你也可以正序去取,这里要注意,对于Lua的很多API,
//下标是从1开始的。这个和C++有些不同。而且,在栈的下标中,正数表示
//绝对栈底的下标,负数表示相对栈顶的相对地址,
//这个一定要有清晰的概念,否则很容易看晕了。

void main() 

 Lua_Call_C();
 C_Call_Lua();



抱歉!评论已关闭.