lua与C交互之——对lua数组的每个元素调用同一个函数

lua面向对象与基于lua的状态机实现 之前一篇文章只是简单的介绍lua的面向对象, 对这方面的理解还很浅,最近在游戏中实现了一个状态机, 这里简单介绍; 思路介绍 状态有很多,需要有扩展性, 所以这里的状态有独立的类结构, 同时状态机作为一个功能要让每个角色对象身上都拥有自己的状态机, 因此也是一个类; 状态机里包含以唯一名字标记对应的状态, 由于状态对于一个游戏角色的行为来说, 可以看作是底层实现, 所以一些公共状态可以 阅读详情

lua程序栈的结构图:以先后传入两个参数"Hello" "Tip"为例
在这里插入图片描述
参考:Lua与C/C++交互——Lua调用C/C++
现在我们需要这样的一个功能,lua中一个数组,tb = {3, 4, 5, 6} ,调用一个function函数,得到的tb = {13, 14, 15, 16},需要这样的一个C库,
main.c

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

static int l_map(lua_State* L)
{
	int i, n;

	//第一个参数必须是一张表
	luaL_checktype(L, 1, LUA_TTABLE);

	//第二个参数必须是一个函数
	luaL_checktype(L, 2, LUA_TFUNCTION);

	n = luaL_len(L, 1); //获取表的大小

	for (i = 1; i <= n; i++)
	{
		lua_pushvalue(L, 2);
		lua_geti(L, 1, i); //压入t[i]
		lua_call(L, 1, 1); //调用f(t[i]),lua_call的第二个参数:传入f中一个参数,lua_call的第三个参数:f的返回值是一个参数
		lua_seti(L, 1, i); //t[i] = result;
	}

	return 0; //没有返回值
}

static luaL_Reg testlibs[] =
{
	{"mapping", l_map},
	{NULL, NULL}
};

__declspec(dllexport)//这个很重要,设置这个函数为外部链接 Linux不需要
int luaopen_mymap(lua_State* L) //函数名很重要,luaopen_xxx,lua脚本require(“xxx”)和xxx.dll、xxx.so,这4个一定要这样,
{
	luaL_newlib(L, testlibs);
	return 1;
}

编译处理C库为mymap.dll

test.lua

local mymap = require("mymap")

local tb = {3, 4, 5, 6}
function each_plus(element)
	return element+10
end

mymap.mapping(tb, each_plus) --执行后tb = {13, 14, 15, 16}

for i, v in ipairs(tb) do
    print(i, v)  --1是位置,v是值
end 

运行结果:

D:\lua_test>lua test.lua
1       13
2       14
3       15
4       16

几个函数的讲解:
luaL_checktype

void luaL_checktype (lua_State *L, int arg, int t);

arg表示参数的位置,t表示要检查的参数类型( lua_type是宏定义,这里传入int)

lua_type的取值为:

#define LUA_TNIL			0
#define LUA_TBOOLEAN		1
#define LUA_TLIGHTUSERDATA	2
#define LUA_TNUMBER			3
#define LUA_TSTRING			4
#define LUA_TTABLE			5
#define LUA_TFUNCTION		6
#define LUA_TUSERDATA		7
#define LUA_TTHREAD			8

从名字可以看出LUA_TNONE表示为空,LUA_TNIL为nil类型,LUA_TBOOLEAN类型等,根据名字可以大致看出含义。

现在我想对lua数组中的每个元素都加上一个num的值,num值由lua的function传入

lua_Number luaL_checknumber (lua_State *L, int arg);

检查位置为arg的参数是否为数字,并且返回这个数字的值。
如果我传入一个字符串,则直接会报错:

lua: test.lua:8: bad argument #3 to 'mapping' (number expected, got string)

对于这个

/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;

#define LUA_NUMBER	double

根据源码查找,发现lua_Number原来是double类型的。
修改后的test.lua为:

local mymap = require("mymap")

local tb = {3, 4, 5, 6}
function each_plus(element, num)
	return element+num
end

mymap.mapping(tb, each_plus, 20) --执行后tb = {13, 14, 15, 16}

for i, v in ipairs(tb) do
    print(i, v)  --1是位置,v是值
end 

运行结果:

D:\lua_test>lua test.lua
1       23.0
2       24.0
3       25.0
4       26.0

修改后的main.c文件为:

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

static int l_map(lua_State* L)
{
	int i, n;

	//第一个参数必须是一张表
	luaL_checktype(L, 1, LUA_TTABLE);

	//第二个参数必须是一个函数
	luaL_checktype(L, 2, LUA_TFUNCTION);

	//第三个参数必须的一个数字类型
	double dValue = luaL_checknumber(L, 3);

	n = luaL_len(L, 1); //获取表的大小

	for (i = 1; i <= n; i++)
	{
		lua_pushvalue(L, 2);
		lua_geti(L, 1, i); //压入t[i],传入f的第一个参数
		lua_pushnumber(L, dValue); //压入dValue,传给f的第二个参数
		lua_call(L, 2, 1); //调用f(t[i], dValue),lua_call的第二个参数:传入f中一个参数; lua_call的第三个参数:f的返回值是一个参数
		lua_seti(L, 1, i); //t[i] = result;
	}

	return 0; //没有返回值
}

static luaL_Reg testlibs[] =
{
	{"mapping", l_map},
	{NULL, NULL}
};

__declspec(dllexport)//这个很重要,设置这个函数为外部链接 Linux不需要
int luaopen_mymap(lua_State* L) //函数名很重要,luaopen_xxx,lua脚本require(“xxx”)和xxx.dll、xxx.so,这4个一定要这样,
{
	luaL_newlib(L, testlibs);
	return 1;
}

在windows上编译C库给lua调用的方法:
https://editor.youkuaiyun.com/md/?articleId=104572573

linux上编译C库给lua调用的方法:
https://blog.youkuaiyun.com/follow_blast/article/details/81779342

lua 与 c/c++ 交互(6) lua调用C++(使用数组 和字符串函数) test.lua --数组操作 a = {1,2,3,4,5,6} swapArray(a,function(t) return t + 1 end) local function printArray(array) for k,v in ipairs(array) do print(k,"\t",v,"\n") end end printArray(a) --分割字符串 a 阅读详情

相关推荐

Lua的底层原理与C#交互原理浅析【更新中】

在Lua的C源码中,表是通过struct定义的,主要是Table结构。这个结构包括指向数组部分和散列部分的指针,以及这些部分的大小等信息。/* 一些标志位 *//* 散列表部分的大小 *//* 数组部分的大小 *//* 数组部分的指针 */Node *node;/* 散列表部分的指针 *//* 散列表的一个自由位置 *//* 元表 */} Table;Lua 虚拟机:Lua 是由 C/C++ 实现的,因此它可以直接与宿主程序(如Unity)进行通信。C# 与 Lua 交互。

weixin_43757333的博客 4856

lua中的handler和function()作为函数参数的不同

在quick-cocos2d-x lua的开发过程中,我们在传递参数的时候需要传入函数作为我们的参数,通常有两种方法,一种是使用function把我们的函数包起来,另一种是用handler将我们的函数封装起来,这两种方法在使用的时候是明显不同的,下面我就要贴出自己在quick中的代码来说明我理解的二者的不同。 首先是handler,如果我们的参数函数本身是没有参数的,那么应该是: local

DerWeltraum 6707

lua调用C++函数

       实际上,我们早就在无形中用到过这个概念了。比如我们在lua的脚本中使用过print函数。由于lua本身就是用C语言实现的,所以lua的print函数也只是调用了C语言的fwrite函数而已。稍后我们会从源码的角度来看一下这个实现,现在首先来说说怎么让lua调用C++的函数。        首先要明确一点,就是lua和C++之间的交互依然是通过栈来实现的,通过栈进行数据交互。那么我...

yulijuanxmu的博客 2001

Lua函数的多个返回值

Lua中的函数的一个很特殊也很有用的性质,即可以有多个返回值。包括一些内置的函数就是这样。比如string.find函数,在给定的字符串中查找一个pattern,如果有匹配的部分,则返回对应的头、尾的两个索引值;如果不存在匹配,则返回nil。当然,用户定义的函数也可以有多个返回值,通过return关键字返回多个结果即可。比如一个返回数组中最大值及其索引的函数:function max(a) lo...

轻轻草原 2762

lua 与 c/c++ 交互(3)c/c++ 调用 lua 数组类型 table

c调用lua数组 上节说的 通过 lua_getfield获取 lua Table,只能 获取 字符型 的 table的值 这是 这个函数 的定义  LUA_API void  (lua_getfield) (lua_State *L, int idx, const char *k); 这一节,补充 一下 获取 数组 型 table test.lua  增加了 一个 数

fuming0210sc的专栏 1950

C/C++与lua二维数组交互的经典范例

最近为了解决skynet的跑得快ai的核心算法性能问题,那么我们自然就用C来写核心算法,之前从来没做过二维数组交互,也是折腾了一番才能正常理解与运行。先看示例代码 //数组计算加一返回数组 int GetCardCal(lua_State* L) { int arrayNum[20][20] = { 0 }; lua_pushnil(L); int index = lua_gettop(L)-1; luaL_checktype(L, index, LUA_TTABLE); //检测传递过来

huangdecai2的专栏 1326

lua实现的状态机

状态机就是管理在不同状态下的操作实现,这里我简单的提一下,大家看代码就懂了。最近学完了lua打算做点游戏,所有先用lua弄清楚一些常用的状态控制。 ------创建状态机制类型三种状态学习,编码,休息 local state = {study="study",code="code",relax="relax"} bobo={nowstate=state.study} ---默认的是学习状态

code change the world 7699

Lua 调用 C 模块中的函数

在之前 “Lua 模块与包” 的文章中,介绍了 Lua 通过require是如何引入一个模块的,其中 C 模块并未展开分享。今天就分享如何构建和使用一个 C 模块作为 Lua 的引入模块。Lua 通过注册 C/C++ 函数,进行感知 C/C++ 函数。一旦 C/C++ 函数用 Lua 表示和存储,Lua 就会通过对其地址的直接引用来调用,Lua 对这些 C/C++ 函数的调用不再依赖于函数名、包的位置以及可见性规则。Github传送门(如果对你有所帮助或喜欢的话,赏个star吧,码字不易,请多多支持)

江澎涌的博客 873

LUA调用有数组参数的C函数

LUA发送一包数据到串口中,发送前需要校验,校验在C完成,所以要将一个数组传递到C那边,代码如下: 1. C代码的校验函数如下 //--- lua中以数组传递参数 static int calc_chksum(lua_State *L) { int i; int DatLen; unsigned char *DatInf; unsigned short crc; if(...

shjhuang的专栏 2421

lua和c/c++交互

lua 和c采用虚拟栈的方式传递数据,栈中的元素是以lua 数据结构的方式存储,

Waorange的博客 1598

C言语实现lua数组

《Programming in Lua third edition》的第29章工程源码

lua与C交互之—对lua数组的每个元素调用同一个函数

lua与C交互之—对lua数组的每个元素调用同一个函数 lua程序栈的结构图:以先后传入两个参数"Hello" "Tip"为例 参考:Lua与C/C++交互——Lua调用C/C++ 现在我们需要这样的一个功能,lua中一个数组,tb = {3, 4, 5, 6} ,调用一个function函数,得到的tb = {13, 14, 15, 16},需要这样的一个C库, main.c #include <stdio.h> #include <string.h> #include &lt

宁静致远的博客 360

C++ 程序稳定运行一段时间后异常中止?vc6 运行库的bug!!!

事件查看器提示:错误应用程序 xxxxxxx.exe,版本 0.0.0.0,错误模块 MSVCRTD.DLL,版本 6.0.9782.0,错误地址 0x00012b40。这是一个通信方面的软件,需要长期运行,在压力测试时,高负荷连续运行一定天数时必定崩溃,而且都是在msvcrtd.dll中崩溃。后来在dump文件中发现调用栈在是MSVCRTD.DLL模块,跟踪代码发现是在void * __cdecl _heap_alloc_dbg(        size_t nSize,        int nBloc

qingflying的专栏 2679

Lua与C API交互全面解析(史上最全的整理)

C API 纵览 Lua 是一个嵌入式的语言,意味着 Lua 不仅可以是一个独立运行的程序包也可以是一个用来嵌入其他应用的程序库。你可能觉得奇怪:如果 Lua 不只是独立的程序,为什么到目前为止贯穿整本书我们都是在使用 Lua 独立程序呢?这个问题的答案在于 Lua 解释器(可执行的 lua)。Lua 解释器是一个使用 Lua 标准库实现的独立的解释器,她是一个很小的应用(总共不超过 500 行的...

昔拉的博客 1万+

ESP32 BLE Mesh Provisioner实战:手把手教你用ESP-IDF配网智能灯泡(附常见错误排查)

本文提供了一份基于ESP-IDF的ESP32 BLE Mesh Provisioner实战指南,详细解析了配网器的核心角色与工作流程。文章手把手教你从工程搭建、代码初始化到核心回调解析,并重点针对常见的‘Model not bound to AppKey’等错误提供了深度排查思路与解决方案,帮助你构建一个稳定可靠的智能照明网关。

desk3的博客 513

顶级的FDE需要拥有哪些技能?

上一篇《》说明白了什么是FDE。这一篇回答下一个问题:要成为顶级 FDE,需要哪些具体的技能?要想弄清楚FDE应该有哪些能力,就得先搞清楚FDE要完成哪些工作。同时,有一点是我们要密切关注的:现在是大模型时代,所以我们不能脱离大模型讨论FDE的能力。我们可以把FDE在客户现场需要完成的工作分为四类:破冰与诊断、价值交付、项目与预期管理、沟通与影响。另有两项元能力贯穿始终。以下按工作类别逐一拆解,每项能力配 1 / 3 / 5 分标准,方便对照自评。文末有完整打分工具链接。

mydeman的学习日志 258

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

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

Cauchy的博客 2679

(35)远程识别(又称无人机识别)(一)

Ardupilot官网关于《Peripheral Hardware》的翻译 —《(35) 远程识别(又称无人机识别)》。

无人机开发(开源Ardupilot) 4万+

lua和C的交互

一个简单的例子struct Posint x;int y;p->x = v;return 0;p->y = v;return 0;return 1;return 1;p->y = y;p->x = x;return 1;int main()//用于创建一个新的lua虚拟机//打开标准库// 将 table 绑定到全局变量 "g_Cfuns"= LUA_OK)//关闭lua虚拟机return 0;

ZZHinclude的博客 1344

海德汉机床采集数据

海德汉数控系统我一般在高端机床上见得比较多。有好多五轴加工精度比较高的机床都用的是海德汉的系统。市面上常见的有530和640等型号。海德汉的采集还是有点难度的,需要对SDK有深度的了解。

若云流风的专栏 1526

【Altium Designer】Off grid pin解决方法

​今天我画完原理图编译时,出现了太多的黄色(出现warning警告提示)Off grid pin警告,这个警告并不是原理图电气连接出问题了,而是元器件或器件PIN脚没有和栅格对齐造成的原因。再编译还是出现这个警告。 最后经过不断翻阅网上经验和实践,才最终解决,本经验详细记录了解决该警告的有效方法。 解决方案:以下是问题解决步骤... ​

夜半少年的博客 7547

LUA调用C函数

文章目录前言Lua调用C的两种方式1. C函数进行调用2. C库进行调用 参考来源: 《Programming in Lua》中的第26章.调用C函数 《lua 5.3中文参考手册》 前言 lua通过一些方式实现对C函数的调用是lua高扩展性的体现。 Lua调用C的两种方式 lua调用C的两种方式其实是在不同的环境下去对C进行调用。 在C中通过lua的基础库函数调用C(通过C函数进行调用) 在lua中调用C(对自己编译的C动态库进行调用) 无论是上面哪种方式去调用C函数,都必须遵

Dr_chaser的博客 2947

2026年3月GESP真题及题解(C++七级):物流网络

2026年3月GESP真题及题解(C++七级):物流网络

王老师青少年编程 1124

Lua调用c模块

一、lua调用c模块总结 1.c函数库成为lua的一个模块 主要做法:将包含c函数的代码生成库文件 linux下是.so windows下是.dll 同时拷贝到lua运行环境的bin下(由于我用的是LuaTool运行环境 所以放在bin下 程序运行默认从bin下找) 这样lua解析器才可以找到.dll文件 2.编写c模块 (1)先编写需要注册的c函...

小不点的博客 9886

使用 ABAP Development Tool 登录 SAP BTP ABAP 环境时,遇到弹出框应该怎么办?

但在实际环境里,隐私模式、第三方 Cookie 禁止、跨站追踪限制、缓存代理误命中、混合内容拦截等因素,都可能让这条跳转链路被打断。等),浏览器会弹出系统原生登录框,请求用户输入账号和口令或做集成认证。只要它们在响应头里出现,浏览器就会理直气壮地弹框,这是协议层的强约定。,最终弹出原生登录框。前端与网关领域有个通用的经验规则:如果你看到了原生登录框,而期望的是带样式的。环境里的登录方式表述为基于浏览器的前端认证,也就是这类重定向式的交互。环境的具体落地,拆出几类常见诱因与排障路径,并穿插真实世界的案例。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 369

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Lua 与C交互

Lua和C之间的交互 (一) Lua 调C函数 什么样类型的函数可以被Lua调用 typedef int (*lua_CFunction) (lua_State *L); 符合类型的函数怎样处理后才可以被Lua调用 使用lua_register或者 lua_pushfunction和lua_setglobal()把...

bitssly的博客 763

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: Lua调用C库之require("xx.xx")类型包的命名规则
下一篇: lua调用C库之——字符串切割存到table中
hp_cpp
博客等级 码龄11年 310粉丝 218原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值