39、Lua 中调用C函数(lua-5.2.3)

Lua可以调用C函数的能力将极大的提高Lua的可扩展性和可用性。

对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们完全可以通过C函数来实现,之后再通过Lua调用指定的C函数。

对于那些可被Lua调用的C函数而言,其接口必须遵循Lua要求的形式,即typedef int (lua_CFunction)(lua_State L)。

简单说明一下,该函数类型仅仅包含一个表示Lua环境的指针作为其唯一的参数,实现者可以通过该指针进一步获取Lua代码中实际传入的参数。返回值是整型,表示该C函数将返回给Lua代码的返回值数量,如果没有返回值,则return 0即可。需要说明的是,C函数无法直接将真正的返回值返回给Lua代码,而是通过虚拟栈来传递Lua代码和C函数之间的调用参数和返回值的。

实例代码

lua 复制代码
// testlua.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <math.h>

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

//待Lua调用的C注册函数
static int add2(lua_State* L)
{
    //检查栈中的参数是否合法,1表示Lua调用时的第一个参数(从左到右),依此类推。
    //如果Lua代码在调用时传递的参数不为number,该函数将报错并终止程序的执行。
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
    //将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
    lua_pushnumber(L,op1 + op2);
    //返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。
    return 1;
}

//待Lua调用的C注册函数。
static int sub2(lua_State* L)
{
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
    lua_pushnumber(L,op1 - op2);
    return 1;
}

//待Lua调用的C注册函数。
static int l_sin (lua_State *L) {
    double d = lua_tonumber(L, 1); /* get argument */
    lua_pushnumber(L, sin(d)); /* push result */
    return 1; /* number of results */
}

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    //将指定的函数注册为Lua的全局函数变量,其中第一个字符串参数为Lua代码
    //在调用C函数时使用的全局函数名,第二个参数为实际C函数的指针。
    lua_register(L, "add2", add2);
    lua_register(L, "sub2", sub2);
    lua_register(L, "l_sin", l_sin);
    //在注册完所有的C函数之后,即可在Lua的代码块中使用这些已经注册的C函数了。
    luaL_dofile(L,"test.lua");

    //if (luaL_dostring(L,testfunc))
    // printf("Failed to invoke.\n");

    //const char *buf = "print('Hello World')";
    //luaL_dostring(L,buf);

    lua_close(L);
    return 0;
}

test.lua

lua 复制代码
function show()  
    print("helloworld") 
    print(add2(1.0,2.0)) 
    print(sub2(20.1,19))
    print(l_sin(1))
end  

show()  

运行结果

lua 复制代码
helloword
3
1.1
0.8414709848079
请按任意键继续。。。
相关推荐
韩仔搭建8 小时前
美乐迪电玩大厅加载机制与 RoomList 配置结构分析
游戏·小程序·开源·lua
老狼孩111221 天前
2025新版懒人精灵零基础及各板块核心系统视频教程-全分辨率免ROOT自动化开发
android·机器人·自动化·lua·脚本开发·懒人精灵·免root开发
珠峰下的沙砾2 天前
如何在 Postman 中,自动获取 Token 并将其赋值到环境变量
测试工具·lua·postman
时光话2 天前
Lua 第9部分 闭包
开发语言·lua
时光话2 天前
Lua 第7部分 输入输出
开发语言·lua
Hy行者勇哥4 天前
使用Postman调测“获取IAM用户Token”接口实际操作
测试工具·lua·postman
加油,旭杏6 天前
【Lua语言】Lua语言快速入门
开发语言·lua
徐同保6 天前
fetch使用put请求提交文件,postman使用put请求提交文件
测试工具·lua·postman
码到成功>_<9 天前
postman使用技巧
测试工具·lua·postman
King.62410 天前
SQL2API 核心理念:如何重构数据服务交付范式
大数据·开发语言·数据库·人工智能·sql·lua