组件工厂
------3D游戏研发

LUA和C之间的函数调用

 


1.1 从C程序调用LUA函数

LUA的函数和普通变量一样也是First Class Variable类型,可以看作函数指针变量参与栈操作。因此调用过程分为如下几个步骤:
  1. 请求LUA函数(指针)入(GLOBAL)栈。
  2. 将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。
  3. 告知LUA虚拟机入栈参数的个数、函数返回值的个数,并调用此LUA函数。
  4. 从栈定获得返回值,先返回的先入栈,然后将返回值显式出栈。

1.2 从LUA脚本调用C函数

LUA没有提供PYTHON那样丰富的类库,因此复杂的功能需要在C程序中定义好,然后通过lua决定调用时机。在LUA库中定义了可以被LUA虚拟机识别的C函数模型:
int functionName (lua_State* L) {....; return 1;}

这样的函数被是一个合法的lua_CFunction类型,将函数注册到LUA虚拟机中以后,就可以在LUA中以普通LUA函数的方式被调用。注册一个C函数的步骤如下:
  1. 声明并定义一个满足上述模型的函数 (eg. myFunInC)
  2. 用字符串为此C函数取一个名称并入栈(eg. myFunInLua)
  3. 将函数(指针)入栈
  4. 调用LUA库的注册函数功能,将上述的名称与函数指针关联
这样就可以在LUA中用myFunInLua()来调用C中的int myFunInC()了

在下面的代码中,我们调用了LUA脚本中的fnEx2函数,返回值从栈中取得,并且要手动出栈。这里,入栈的函数参数会由pcall自动清理。

2.1 LUA测试脚本代码

[转]LUA C 互调function fnex2(str_a, num_b, num_c)
[转]LUA C 互调    print(str_a);
[转]LUA C 互调    return num_b*100 + num_c*10"Thank you";
[转]LUA C 互调end;


2.2 VC代码

[转]LUA C 互调//初始化LUA虚拟机
[转]LUA C 互调void InitLuaState(lua_State* L)

2.3 工具

下面的宏可以简化调用lua函数的代码:
[转]LUA C 互调#define CallLuaFunc(FuncName, Params, Results) 



3. 从LUA调用C函数示例

在下面的例子中,我们注册一个名为rmath的LUA函数,他在C中的函数名为RMath_LUA()

3.1 LUA脚本代码

[转]LUA C 互调print (">>> LUA程序开始运行了 ");
[转]LUA C 互调
[转]LUA C 互调function fnex3(num_a, num_b)
[转]LUA C 互调    local c = rmath(num_a, num_b);
[转]LUA C 互调    print("LUA PRINTTING:", c);
[转]LUA C 互调    return c;
[转]LUA C 互调end;


3.2 VC程序代码

[转]LUA C 互调//LUA脚本调用C函数
[转]LUA C 互调int call_c_function(void)


4. 程序解释

4.1 调用LUA脚本中的函数

调用LUA脚本函数主要用到如下几个LUA库函数:
);

通过lua_getglobal请求函数(指针)入栈,然后将函数参数按声明顺序入栈,调用lua_pcall执行函数。lua_pcall的第一个参数 指向LUA虚拟机,第二个参数表示栈顶有多少个函数参数,第三个参数表示此函数将返回几个值。(pcall自动清理入栈的参数,返回值则需要手动 pop。)

4.2 从LUA调用C函数

主要用到如下几个函数,为求方便您也可以自己定义这样的一个宏。
[转]LUA C 互调    lua_pushstring(L, "rmath");
[转]LUA C 互调    lua_pushcfunction(L, RMath_LUA);
[转]LUA C 互调    lua_settable(L, LUA_GLOBALSINDEX);[转]LUA C 互调

  • 函数名入栈
  • lua_CFunction类型的函数指针入栈
  • 调用lua_settable注册函数
这样就可以在lua脚本中调用rmath()函数了。

相关文章:

  • 2021-09-26
  • 2022-12-23
  • 2021-07-31
  • 2021-06-11
  • 2021-12-20
猜你喜欢
  • 2021-11-19
  • 2021-06-15
  • 2022-12-23
  • 2021-09-03
  • 2022-02-23
  • 2021-05-28
相关资源
相似解决方案