在C语言中调用lua实现的回调函数

xlua源码分析(三)C#访问lua的映射 XLuaTestInvokeLuaICalcBridge是继承自ICalc接口的类,它负责实现ICalc的功能,也就是我们一开始提到的一个PropertyChanged的event +=和-=操作,一个Add方法,一个Multi属性,以及下标操作符。代码逻辑很简单,就是准备调用环境,然后把C#的参数push到lua层,然后pcall调用,然后从lua栈中取出返回的结果,由于lua是弱类型的,无法事先知道返回值的类型,所以这里只能使用通用的GetObject函数对lua的返回值进行类型转换。 阅读详情
在内嵌的lua代码中,想要实现以下功能:
function callback(n)
    print("function callback " .. n);
end;

save_callback(callback, "aaa")
invoke_callback() -- 这里打印出function callback aaa

save_callback(function(n)
    print("anonymous function callback " .. n);
end
, 1)
invoke_callback() -- 这里打印出anonymous function callback 1


即:save_callback函数传入回调函数对象和1个参数,然后在任意时刻使用保存的参数和函数对象进行回调。


以下是实现的C代码:


#include <lua.h>
#include <lauxlib.h>
int callback_indicie;
int param_indicie;

/* by superarhow, 2014/03/04 */

int save_callback(lua_State* L)
{
    param_indicie = lua_ref(L, 1);
    callback_indicie = lua_ref(L, 1);

    return 0;
}

int invoke_callback(lua_State* L)
{
    lua_getref(L, callback_indicie);
    lua_getref(L, param_indicie);
    int ret = lua_pcall(L, 1, 0, 0);
    if (ret != 0) {
        lua_error(L);
    }

    return 0;
}


int main(int argc, char** argv)
{
    lua_State* lua = lua_open();

    luaL_openlibs(lua);

    lua_register(lua, "save_callback", save_callback);
    lua_register(lua, "invoke_callback", invoke_callback);

    luaL_dofile(lua, "test.lua");

    lua_close(lua);
    return 0;
}


注意:

* 因为是例子程序所以用全局变量来保存回调函数和其参数的索引,实际应用中应与其对象关联。可以用C closure实现关联对象,也可以往lua_State中存入全局light userdata指针;

* 注意lua_ref这个函数:lua_ref(L, 1) -> 这里的1不是栈索引,而是指"是否加锁",0为不加锁,非0为加锁。偶使用的版本还不支持不加锁。

  另外,lua_ref是luaL_ref的简化版本,luaL_ref要求提供一个table指出ref之后的变量应该保存在哪个位置(否则的话你就再也找不到它了。什么?用栈索引?要知道lua为每次函数调用都新分配了一个栈的,因此在离开作用域之后,栈索引就失效了。)lua_ref使用全局table LUA_REGISTRYINDEX来存放ref。它假设你不会对LUA_REGISTRYINDEX这个table进行增删改的操作,因此返回的这个索引(指向在LUA_REGISTRYINDEX表中的array part部份的位置)是一直有效的。

  既然没有提供栈索引,那么它是对哪个对象创建引用?它会对栈尾(最后一个入栈的)对象增加引用计数,保并且会pop掉它。会不会破坏栈平衡?前面已经说过lua会为每次函数调用分配一个新的栈,因此只要这个函数内没有后续操作就可以不用管它。

* 例子中没有调用lua_unref。实际使用时要在使用完毕后调用lua_unref释放掉这些引用。


【Lua 语言】Lua 调用 C 函数 Lua 提供了调用 C 函数的接口,这样我们可以开心地用 C 来写一些底层的代码供 Lua 调用了。调用方式如下:1. 新建 C 源文件,将需要被 Lua 调用的函数实现如下:static int l_add(lua_State *L){    return 0;}... 阅读详情

相关推荐

Lua学习笔记--C调用Lua

Lua是一种嵌入式语言,可以很好的嵌入其他应用程序。lua为我们提供了一组灵活的C API,使C代码能够很好的与Lua进行交互。包括读写Lua全局变量,调用Lua函数,运行Lua代码,注册C函数反过来供Lua调用。简单的说,C能调用Lua,反过来Lua也能调用C。真的是灰常强大灵活的脚本!!现在,先来学习一下怎么用C调用Lua。 其实最简单的我们已经做过了,通过一个dofile,运行一个lua脚

puppet_master的专栏 2556

向lua虚拟机传递信息

当程序逻辑交给脚本跑了以后,C/C++ 层就只需要把必要的输入信息传入虚拟机就够了。当然,我们也需要一个高效的传递方法。  以向 lua 虚拟机传递鼠标坐标信息为例,我们容易想到的方法是,定义一个 C 函数 get_mouse_pos 。当 lua 脚本中需要取得鼠标坐标的时候,就可以调用这个函数。  但这并不是一个好方法,因为每次获取鼠标坐标,都需要在虚拟机和 native code 间

分享建筑软件的乐趣 1423

Lua知识点_高级_c++中调用Lua回调函数

以下是在cocos2dx-3.10 lua中 1.概述 以下主要用于lua中执行了c++函数,在c++函数执行完成后,调用Lua的回调函数。 2.实例 frameworks   --runtime-src     --Classes       --test.cpp  --RegisterToLua.cpp src-- --main.lua --app

haibo19981的专栏 1998

c++调用lua脚本中局部函数

lua代码: //这是一个lua中的局部函数 local function Test()   print("I am Test in Lua\n") end   DoSomeThing(Test) #include "stdafx.h" #include "stdlib.h" extern "C" { #include "lua.h" #include "laux

qq_36453052的博客 876

KEPServerEX中,别名映射(Alias Mapping)数据标签重命名机制

目录核心机制应用场景配置步骤技术特性与参考内容的差异KEPServerEX中,别名映射(Alias Mapping) 是一种数据标签重命名机制,主要用于简化复杂标签路径的调用或实现跨系统兼容。其核心逻辑和功能如下:路径抽象 将设备层级结构中的完整标签路径(如 Channel1.Device1.Tag1)映射为简短别名(如 TempSensor1),降低客户端调用的复杂度。动态绑定 别名与实际标签实时关联,数据更新和读写操作通过别名直接传递到底层物理标签,无需修改客户端配置。多对一映射支持多个别名指向

「东哥说MES」 专注于MES制造执行系统,为你拆解核心架构、功能模块及与ERP/PLC的集成逻辑。提供从入门到精通的系列干货、精选行业报告与实用工具,构建你的数字化知识体系,关注我,用实战经验照亮你的数字化之路。 1591

交叉熵损失函数基本概念及公式

对于二分类问题,模型的输出通常是一个标量,表示样本属于正类的概率。因此,在二分类的交叉熵损失函数中,我们只需要考虑一个概率值,即模型预测为正类的概率。具体来说,当真实标签为1时,我们关注模型预测为正类的概率;当真实标签为0时,我们关注模型预测为负类的概率。因此,二分类的交叉熵损失函数可以表示为:其中,y 表示真实标签,取值为 0 或 1;p 表示模型预测为正类的概率。而对于多分类问题,模型的输出通常是一个向量,表示样本属于各个类别的概率。因此,在多分类的交叉熵损失函数中,我们需要考虑所有类别的概率。

qlkaicx的博客 1万+

c语言函数回调详解,C语言模块回调Lua函数的两种方法

lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平衡稍微会多写一点代码。 今天分享学到的C模块回调Lua函数的两种方法,都是炒冷饭,大侠勿喷。1. C保存函数对象C模块可以通过注册表保存Lua里面的对象,等适当时候取出再调用即可。复制代码 代码如下:static int lua_callback = LUA_REFNIL;static int setnotify(lua_State *...

weixin_29281915的博客 276

基于三轴加速度计的塑料水管泄漏振动检测技术全解析

在流体力学与结构动力学领域,管道振动分析是评估系统健康状态的关键技术。其基本原理在于,当管道内流体状态发生异常(如泄漏)时,会引发管壁产生特定的机械振动信号。这项技术的核心价值在于实现了对管道系统的非侵入式、在线监测,能够提前预警潜在故障,避免资源浪费与次生灾害。在智慧城市与智能水务等应用场景中,它对于保障供水管网安全、提升运维效率具有重要意义。本文聚焦于如何利用高精度的三轴加速度计,精准捕捉塑料水管因泄漏产生的微弱振动,并通过信号处理与机器学习算法,构建一套从数据采集到泄漏识别与定位的完整工程解决方案。

weixin_32239523的博客 407

XLua 原理分析 三

Xlua 通信调用

qq_25978293的博客 1415

128x64 OLED屏的救星:手把手教你用纯C实现轻量级多级菜单

本文针对资源受限的单片机开发场景,提供了一套用纯C语言实现128x64 OLED屏轻量级多级菜单的完整方案。该方案摒弃了传统的树形指针结构,创新性地采用哈希表进行菜单项管理,核心代码不足200行,内存占用极低,逻辑清晰且易于维护。文章详细阐述了架构设计、实战演练及性能优化技巧,是STM32、ESP8266等小内存MCU项目的理想选择。

table的专栏 228

Proteus 8.9仿真五路抢答器:从74LS148编码到NE555报警的保姆级电路拆解

本文详细解析了使用Proteus 8.9仿真五路抢答器的完整设计流程,从74LS148优先编码器到NE555定时报警电路。通过保姆级的电路拆解和芯片选型指南,帮助读者掌握数字电路中的编码、锁存、译码和定时等核心技术,实现稳定可靠的抢答系统仿真。

weixin_30836759的博客 380

c语言怎么调用lua库函数,在C语言中调用lua实现的回调函数

在内嵌的lua代码中,想要实现以下功能:function callback(n)print("function callback " .. n);end;save_callback(callback, "aaa")invoke_callback() -- 这里打印出function callback aaasave_callback(function(n)print("anonymous func...

weixin_30516835的博客 464

2025.05.29【Network】多组学分析:网络互作图绘制

本文介绍了使用R语言进行网络图绘制的方法与技巧。重点讲解了三个核心R包的使用:igraph用于网络图数据准备与基础绘制,ggraph基于图形语法实现高级可视化,networkD3则为网络图添加交互功能。文章涵盖了从基本概念、包安装、创建网络图对象,到自定义样式布局、添加交互性等完整流程,并提供了度分布、聚类系数等网络分析指标的计算方法。通过清晰的代码示例,帮助读者掌握生物信息学数据可视化的关键技能,为复杂数据的直观展示和分析提供实用工具。

227

c++调用lua注册的带参数的回调

main.cpp int lua_cb = LUA_REFNIL; int lua_cb_arg = LUA_REFNIL; int setcb(lua_State *L) { lua_pushvalue(L, -2); lua_callback = luaL_ref(L, LUA_REGISTRYINDEX); lua_pushvalue(L, -1);...

weixin_30258027的博客 187

【OpenClaw从入门到精通】第15篇:国产芯片适配实战——昇腾/龙芯/天数智芯全流程跑通(2026实测版)

2026年国产芯片AI适配迎来爆发期,OpenClaw作为轻量化本地AI智能体,已实现华为昇腾、龙芯、天数智芯等主流国产平台的全流程适配。本文基于实测数据,从背景解析、核心原理、算法优化、实操部署四个维度,详细讲解OpenClaw在香橙派昇腾开发板、龙芯3B6000M、天数彤央TY1200及联想开天X7h的部署流程,同时提供统一工具玄武CLI的使用指南。文中包含完整代码、执行结果、避坑技巧及虚拟实战案例,兼顾新手入门与进阶提升,帮助读者快速掌握国产芯片上的本地AI部署能力,实现数据隐私保护与低成本AI落地。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1008

endNote X9 增加 / 删除参考文献 文献编号自动更新

EndNote X9 插入参考文献常见问题总结。增删参考文献 文献编号自动更新

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 7497

Lua与C语言的互相调用

Lua底层是C语言开发的,在设计时就考虑到了与C语言的互操作性。可以把Lua作为一种独立的语言或者作为一种嵌入式的脚本语言。有许多游戏和其他应用程序利用Lua作为脚本语言。 在本文中,我们将重点探讨如何将Lua嵌入到C或C++应用程序中,作为胶水脚本存在。虽然此文只关注C语言的API,但在LuaDardo项目中,这些C API并没有做根本改变,只是在命名规范上做了适应Dart语言的变化(驼峰命名法)。简单说,LuaDardo基本是兼容这些API的。 使用 C API Lua的C语言API是高效和轻量级的。在

编程之路的专栏 7726

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

在Lua中调用C语言

文章目录C函数延续C模块   我们说用Lua可以调用C语言函数,但这并不意味着Lua可以调用所有的C函数。当C语言调用Lua函数时,该函数必须遵循一个简单的规则来传递参数和获取结果。同样,当Lua调用C函数时,这个C函数也必须遵循某种规则来获取参数和返回结果。此外,当Lua调用C函数时,我们必须注册该函数,即必须以一种恰当的方式为Lua提供该C函数的地址。   Lua调用C函数时,也使用一个与C语言调用Lua函数时相同类型的栈,C函数从栈中获取参数,并将结果压入栈中。   此处的重点在于,这个栈不是一个全局

2800

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Lua和C语言交互入门

Lua本身的设计时就有为了可以方便的嵌入到别的语言中使用的功能,主要来说就是可以方便的嵌入到C语言中,并和C语言进行交互。这篇文章将对相关内容进行介绍。

Naisu的各种笔记 3327

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【C & Lua】C调用Lua | Lua调用C

Lua与C交互是一种非常常见的技术,它可以让我们在C语言中调用Lua脚本,也可以让我们在Lua脚本中调用C语言函数。这种交互方式可以使得我们在不同的编程语言之间实现混合编程,从而达到更高的灵活性和效率。Lua栈是Lua与C交互的核心数据结构,所有的数据交互都是通过Lua栈来完成的。无论是从Lua中调用C函数,还是从C中调用Lua函数,都需要使用Lua栈来传递参数和返回值。

Cauchy的博客 2679

C语言调用lua

C语言是一种非常流行的编程语言,而Lua是一种基于C语言开发的脚本语言。相信大家都知道,Lua可以使用C语言来扩展其功能,进而实现更复杂的功能。而在Lua的各种实现中,luajit也是其中一种非常流行的实现。

风声的专栏 2139

C语言调用Lua脚本

最近由于公司技术需要,开始研究lua,刚开始看文档知道lua是一个脚本,用于拓展的,今天就研究了一下在c语言中的调用。 我是看到了一个文档,然后照着做的: http://www.cnblogs.com/pied/archive/2012/10/26/2741601.html 不过这个文档可能是时间久了,有的地方不是那么顺利,下面是我的每一步的操作。     首先介绍一下我的环境,我是在

ChamPly 6973

C语言与Lua之间的相互调用详解

C语言与Lua之间的相互调用详解写一个C调用Lua的Demo编译运行C语言调用Lua编译问题总结正确的编译命令问题1:缺少-lm参数问题2:缺少-ldl参数​1、为什么会出现undefined reference to ‘xxxxx’错误?​2、-l参数和-L参数 写一个C调用Lua的Demo编译运行 add.c内容 //你需要include这几个lua头文件 #include <stdio.h> #include "lua.h" #include "lualib.h" #include

宁静致远的博客 2872

Lua中调用C函数

Lua中调用C函数Lua利用一个虚拟的堆栈来给C传递值或从C获取值1. C函数作为应用程序的一部分2. C函数库成为Lua的模块Lua中调用C函数Lua调用c模块 https://www.cnblogs.com/sifenkesi/p/3876745.html https://blog.youkuaiyun.com/liu943367080/article/details/90909005 Lua利用一个虚拟的堆栈来给C传递值或从C获取值 Lua利用一个虚拟的堆栈来给C传递值或从C获取值。每当Lua调用C函数,都会获得

宁静致远的博客 3923

从lua调用C

1.环境 1.1 lua版本 我使用LuaForWindows_v5.1.4-46安装的lua环境,lua版本是5.1 1.2 vs版本 vs2013 1.3 vsvode vscode版本是1.44.2,安装了一个Lua Debug的插件来调试lua,版本是1.29.1。 2.lua调用c Lua利用一个虚拟的堆栈来给C传递值或从C获取值。每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回值压入这个栈(Lu

lemon 2988
上一篇: 关于C++多线程程序中简单类型(int/bool)的安全性
下一篇: 关于std::string出现在_M_dispose发生SIGABRT错误的问题
superarhow
博客等级 码龄23年 46粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值