惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Last Watchdog
The Last Watchdog
博客园_首页
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
美团技术团队
小众软件
小众软件
V
V2EX
博客园 - Franky
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The GitHub Blog
The GitHub Blog
Microsoft Security Blog
Microsoft Security Blog
Attack and Defense Labs
Attack and Defense Labs
S
Security Affairs
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
T
The Exploit Database - CXSecurity.com
有赞技术团队
有赞技术团队
S
Schneier on Security
人人都是产品经理
人人都是产品经理
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
PCI Perspectives
PCI Perspectives
AI
AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
O
OpenAI News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
博客园 - 【当耐特】
C
Cisco Blogs
大猫的无限游戏
大猫的无限游戏
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
S
Securelist
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Proofpoint News Feed
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
L
LangChain Blog
SecWiki News
SecWiki News
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V2EX - 技术
V2EX - 技术
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
L
LINUX DO - 热门话题
Cisco Talos Blog
Cisco Talos Blog

远飞闲记

用 OpenClaw 搭建全自动晨间简报系统 Open Claw(🦞龙虾): 新手最常踩的 8 个坑,我帮你踩过了 什么是AI Agent(智能体)? OpenClaw 在微信端使用指南 如何让OpenClaw🦞更好用-调教篇 OpenClaw(龙虾🦞)自主赚钱实验笔记 本地Qwen+云模型:OpenClaw真实体验 AI博客主题开发记 OpenClaw初试记 十年博客路:在AI水文泛滥的时代,为何还在坚守? AI Coding实战吐槽:别被"400刀大神"带偏,这些坑我帮你踩过了! 《相信》把不可能变为可能 我们写的程序被杀毒软件杀了,杀毒软件到底杀了什么? 👋2024 探索Unity单元测试:构建可靠游戏代码的基石 实用小黄鸭调试法 炸裂的Unity割韭菜这事 还是要有信念 您好2023 Docker启动提示虚拟化失败 Golang中配置文件热重载方案 重置博客主题 双链知识管理及logseq使用体验 魔幻的魔都疫情 漫谈国内NFT市场状况 如何在UE4中平衡蓝图与C++的使用 2021时光荏苒,2022可遇可期 UE4(Unreal Engine)本地化资源功能 摈弃:“拥有更多=做的更好的”的观念 鱿鱼游戏 研究UE4(虚幻引擎)后的感想 初试Caddy WebServer GitHub Copilot AI编程的感受 Mac Mini M1真香定律 地震提醒App 共和国失去两大功勋 币圈还好吗? Headless CMS 倒牛奶事件 “鸡娃”现象的观点 2020年新冠期间记录 社区团购团长的入门到放弃 路由折腾记 多电脑鼠键共享方案 Typescript循环引用 Circular Referenec 问题解决方法 《高效清单工作法:聪明人的无压时间管理手册》 Crossword Puzzles Privacy ShareTheCookies Privacy 七月的最后一天 游戏开发中使用的概率算法 笔直站立昂首挺胸的生活态度 Android和H5网游加速器解决方案的探索 Golang基础配置和Go Emacs开发环境的配置 使用Github Actions自动发布Hugo Blog配置 《青年到此为止》读书随笔 逛T推遇见比较有意思的事 GnuGPG Git中的使用及配置 《极简主义:活出生命的真意》阅读记录 疫情记录:热干面出院了 如何有效的阅读一本书:葱鲔火锅式笔记读书法 《麦肯锡精英高效阅读法》读书笔记 2020四年之约 疫情记闻 2020-二月二龙抬头 任天堂(Nintendo)switch NS游戏机 真香 MacBook Pro SSD 512G硬盘升级记 构建Facebook Instant Game本地测试环境 今日有感 Bye 2019,Hi 2020 猎魔人-The Witcher 如何判断是否适合加入创业团队 开发人员业余项目版权的见解 容易改变想法的人 及时止损 VSCode中远程调试NodeJS配置 Android Google Play 内购服务器订单校验 做产品是否要蹭热度 为什么会接入Google Adsense 成功和产品体验的一点想法 共享经济下的牺牲品们 折腰的梯子们 Emacs配置:Unity项目开发配置 人人都想当管理者 对焦虑和迷茫的理解 TypeScript强类型判断引发的问题 找回习惯和中产与爱好 程序员的成长之路 产品、技术、团队 爱心被滥用 工作996.生病ICU 2019初一记事 忆上海,换一种生活方式 记一次地震时的感受 押金是什么 Egret Jenkins搭建构建环境中遇见的坑 去年的总结 要懂的感恩 阿里云OSS+docker Owncloud安装 从修建房子来说开发过程的问题和流程 小记录 与人方便,与己方便
Lua和C/C++的数据交互
2015-08-23 · via 远飞闲记

近日重新复习了下C\C++和Lua之间的数据交互知识,在这里也做一个简单的记录来作为以后的参考.

Lua栈操作的介绍

Lua是一种嵌入式的脚本语言,不是独立运行的程序它可以通过链接对其他语言进行扩展,或让其他的语言来使用Lua的功能.其中包括使用lua作为库存在于C中或Lua作为主导权C作为一个库来使用.

lua和C语言的交互都是在一个虚拟栈进行的,所有的API操作都是对栈上的数据进行交互.无论是C到Lua的操作还是Lua到C的操作.这里会存在两个问题

  1. 动态类型和静态类型之间的区别,lua是动态性的语言,而C是静态语言
  2. 自动内存管理和手动内存管理的区别.

lua没有采用C语言的联合来解决动态和静态的区别,其原因是不仅为C一门语言设计的保持Lua的宿主可以是任何一门语言。其次Lua是有垃圾回收机制的如果lua table保持在C变量中,Lua引擎则无法搜索出来回收.所以Lua会使用一个抽象的棧来对Lua和C之间的数据交互.

Lua的栈严格按照(LIFO)先出后进的规范来操作栈,栈中任何元素都保存着lua中的任何类型:

  1. 获得lua中的一个值,调用Lua API函数,Lua会将指定的值压入栈,
  2. 要将一个值传给Lua时则先要将这个值压入栈,调用Lua API函数,Lua则会把获取该值并将其从栈中弹出.

压栈操作会把第一个压入的元素索引标记为1,第二个为2,依次推至栈顶,使用负数来访问栈中元素,-1表示栈顶的元素.

相关API

压入栈:lua_push* (..)
检查元素类型: lua_is*(..)
栈中取出值: lua_to*()
检查栈是否有足够的空间:lua_checkstack(lua_State *l,int size);
返回栈中元素个数:lua_gettop(..)
将栈顶设置为一个指定位置: lua_settop(..)
栈中弹出指定个数的元素:lua_pop(..)
将索引上的值副本压入栈:lua_pushvalue(..)
删除栈中指定位置的元素:lua_remove(..)
移动指定元素空间开辟一个槽空间,将栈顶元素移到该位置: lua_insert(..)
移动栈顶的元素到指定位置:lua_replace(..)
*: string\nil\number\boolean\integer 

C中调用Lua

比如lua文件中有一个全局变量的table: conf={w=20,h=10}


lua_stack* L = luaL_new_state();
luaL_openlibs(L);

lua_dofile("lua文件");

lua_getglobal(lua_stack*,"conf");
if(!lua_istable(lua_stack*,-1))
{
  printf("conf全局变量不是一个table")
}
//获取W的值
lua_pushstring(L,"w");
lua_gettable(L,-2)
if(!lua_isnumber(L,-1))
{
 printf("%s不是一个数字","w");
 }
 int w_val = lua_tonumber(L,-1);
 lua_pop(L,1);

//调用lua中方法
lua_getglobal(L,"方法名");
//这里可以压入参数值
lua_pushstring(L,"参数值")
//状态引用,参数个数,是否有返回值
if(lua_pcall(L,1,1,0)!=0)
{
  printf("函数调用失败 Error:%s",lua_tostring(L,-1));
}
//获取返回值
if(lua_isnumber(L,-1))
{
  int res_value = lua_tonumber(L,-1);
}
lua_close(L);

Lua调用C/C++

注册C/C++函数到Lua中

int mysin(lua_State* L)
{
//获取lua中的值
  int str = luaL_checknumber(L,1);
  printf("lua中传入参数的值:%d",str);
//获取第二个参数,调用lua方法
if(lua_isfunction(L,2))
{
   if(lua_pcall(L,0,0,0)!=0){
      printf("调用函数出错");
    }
}

//压入返回值到lua中
lua_pushstring(L,"这里是返回给lua的值");

return 1;
}

....

//压入函数到栈中
lua_pushcfunction(L,mysin);
lua_setglabal(L,"mysin");
....

lua中直接调用: local res=mysin(10,function()
   print("这里是参数函数")
end);


Lua调用C/C++中的自定义类型

//自定类型绑定到lua中
struct MyType{
  int size;
}

static int mytype_new(lua_State* L)
{
MyType** mytype = (MyType**)lua_newuserdata(L,sizeof(MyType*));
*mytype=new MyType();
luaL_getmetatable(L,"feiio.MyType");
lua_setmetatable(L,-2);
   return 1;
}


static int mytype_getType(lua_State*L)
{
//这里获取创建的对象
MyType **mytype=(MyType**)luaL_checkudata(L,1,"feiio.MyType");
int size = (*mytype)->size;
lua_pushnumber(L,size);
 
 return 1;
 }

//Lua执行对象回收机制销毁对象时调用
static int mytype_gc(lua_State* L)
{
MyType** mytype = (MyType**)luaL_checkudata(L,1,"feiio.MyType");
if(mytype)
{
  delete mytype;
  }
  return 0;
}

int initMyType(lua_State* L)
{
static const luaL_Reg mylib[]={
{"new",mytype_new},
{NULL,NULL}
};

static const luaL_Reg myfunc[]={
{"getType",mytype_getType},
{"__gc",mytype_gc},
{NULL,NULL}
}
//实现面向对象的支持
luaL_newmetatable(L,"feiio.MyType");
lua_pushvalue(L,-1);
lua_setfield(L,-2,"__index");
lua_setfuncs(L,myfunc,0);
  luaL_newlib(L,mylib);


return 1;
  }

//main函数中
.....
initMyType(L);
luaL_requiref(L,"MyType",createType,1);
lua_settop(L,0)
.....

//Lua中调用
local mytype=MyType.new()
//面向对象的方式获取
mytype:getType()

相关资料

使用C++模板来绑定Lua Lua教程:绑定一个简单的C++类(6)