Lua C++交互 应用实例步骤(UserData使用)
一.配置Lua C++交互环境
1.下载Lua 包环境
地址: https://www.lua.org/download.html ,我们这里用的是5.4.2版本。
2.新建C++ 控制台应用程序
3.导入Lua 源码
1)导入Lua 源码到同级目录(这样做为了Main函数所在类添加Lua 的C 类的时候直接可以include,不需要考虑目录层级问题)

打开的目录里,将5.4.2 的lua包里的 src目录里的文件全部拷到此目录
2)添加Lua 源码

选中刚刚导入的Lua文件
3)编译
这时,点击目录生成,回发现报错

这是关键报错信息,重复main头文件,众所周知,main函数是启动函数;那就注释调main.
会发现,有两处main ,lua.c 中 int main 和luac.c int main,分别都注释了。(或者简单粗暴,直接将luc.c和luac.c直接删除也可以)
再点生成,成功。这两处main,其实就是如果你将此lua编码打包成exe,就是启动函数。但是我们这里不需要这边的main,我们自己新建的C++ 应用程序,是有自己的Main。
二.Hello.lua 运行
新建Lua脚本,必须.lua 结尾。

1.关键API
1)lua与C++交互,必须要一个虚拟栈。可通过lua_State* L = luaL_newstate(); 对于栈的介绍可参考:https://blog.csdn.net/shun_fzll/article/details/39120965,这里就不对栈作描述了。
2)加载Lua文件,可通过 luaL_dofile 返回一个 int类型,返回结果不为0,则表示异常
3)Lua有异常,会把返回结果返回到栈顶,也就是说报异常了,可以通过lua_tostring(L,-1)得到报啥错,再打印出来.
4)lua_close 就是释放这个栈。
5)对于C++调用 C的头文件,需要extern
2.实例分析
1 #include <iostream>
2 #include <string.h>
3 using namespace std;
4 extern "C"
5 {
6 #include "lua.h"
7 #include "lualib.h"
8 #include "lauxlib.h"
9 }
10 int main()
11 {
12 std::cout << "Hello World!\n";
13 lua_State* L = luaL_newstate();
14 int Ret = luaL_dofile(L, "LuaHello.lua");
15 if (Ret)
16 {
17 string strError = lua_tostring(L, -1);
18 cout << strError.c_str() << endl;
19 return -1;
20 }
21
22 lua_close(L);
23 return 0;
24 }
1)运行上述代码

2)想一下,好像lua代码是运行了,但是print怎么会nil,并报错,提示的还挺智能,具体行号都报出来了。
我们再试着修改Lua代码中下移两行试试:

3)咦,那就证明Lua文件是肯定运行了,就是异常了。找不到print,print不是lua库里的函数嘛,为啥拿不到了。
因为C++环境中创建Lua_State这个栈,这个默认并没有打开lua标准库。所以查一下。
在 上述Line:13 后面新增 luaL_openlibs(L);
运行 得到 
恭喜,C++ 与Lua通信成功。
三.Lua UserData应用实例
关于具体lua与C交互的一些常见操作,可参考:https://blog.csdn.net/shun_fzll/article/details/39120965
问题:有时候,你会想,我在C++中声明了一个struct,在lua中,也想声明这个struct,怎么弄纳?接下来这个案例就是教你如何使。
我们的UserData就是解决这个问题的。
Lua UserData分两种,我们这说的是FullUserData,就是可以解决上述问题的UserData.
直奔主题,看代码分析。
Lua5.1之前和之后的注册函数差距很大,详情可参考:https://blog.csdn.net/ljhjason/article/details/28860633
Lua5.1之后可以使用 luaL_requiref 代替 Lua5.1之前的luaL_register ,可参考:https://blog.csdn.net/ljhjason/article/details/28860633
1 #include <iostream>
2 #include <string.h>
3 using namespace std;
4 extern "C"
5 {
6 #include "lua.h"
7 #include "lualib.h"
8 #include "lauxlib.h"
9 }
10
11 struct TestCStruct
12 {
13 char* Name;
14 int Num = 1;
15 };
16
17 int NewTestCStruct(lua_State* L)
18 {
19 size_t iBytes = sizeof(struct TestCStruct);
20 struct TestCStruct* pStruct = (struct TestCStruct*)lua_newuserdata(L, iBytes);
21 return 1;
22 }
23
24 int SetNum(lua_State* L)
25 {
26 struct TestCStruct *pStruct = (struct TestCStruct*)lua_touserdata(L, 1);
27 luaL_argcheck(L, pStruct != NULL, 1, "Error Param");
28 int num = luaL_checkinteger(L, 2);
29 luaL_argcheck(L, num > 0, 2,"Wrong Paramter");
30 pStruct->Num = num;
31 return 1;
32 }
33
34 int GetNum(lua_State* L)
35 {
36 struct TestCStruct *pStruct = (struct TestCStruct*)lua_touserdata(L, 1);
37 luaL_argcheck(L, pStruct != NULL, 1, "ErrorStruct");
38 lua_pushinteger(L, pStruct->Num);
39 return 1;
40 }
41
42 struct luaL_Reg arrayFunc[] = {
43 {"new",NewTestCStruct},
44 {"SetNum",SetNum},
45 {"SNum",GetNum},
46 {NULL,NULL}
47 };
48
49 LUALIB_API int luaopen_mytest(lua_State* L)
50 {
51 luaL_newlib(L, arrayFunc);
52 return 1;
53 }
54
55 int main()
56 {
57 std::cout << "Hello World!\n";
58 lua_State* L = luaL_newstate();
59 luaL_openlibs(L);
60 luaL_requiref(L, "mytest", luaopen_mytest, 0);
61 int Ret = luaL_dofile(L, "LuaHello.lua");
62 if (Ret)
63 {
64 string strError = lua_tostring(L, -1);
65 cout << strError.c_str() << endl;
66 return -1;
67 }
68
69 lua_close(L);
70 return 0;
71 }
Lua中源码
local t = require("mytest")
print("t:" .. tostring(t))
local y = t.new()
print("y :" .. tostring(y))
t.SetNum(y,100)
print("Num:" ..t.SNum(y))
local y2 = t.new()
print("y2 :" .. tostring(y2))
print("Hello lua and C++")
运行结果

综上, 可以看到Full UserData 的使用,主要核心是Line:60 luaL_requiref的使用。
Lua C++交互 应用实例步骤(UserData使用)的更多相关文章
- JS在与lua的交互心得
最近在写一个项目,前端技术使用的是Vue,在与lua的交互过程,是通过一个公共JS,前端调用公共js的方法给lua发送命令,lua接到命令,去执行一些方法,然后又通过回调返回到了前端,由于是第一次写这 ...
- react UI交互 简单实例
<body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...
- 第4章-Vue.js 交互及实例的生命周期
一.学习目标 了解实例生命周期的过程 理解钩子函数的作用 掌握Vue.js过滤器的使用方法 (重点) 能够使用网络请求进行前后端交互 (重点.难点) 二.交互的基本概念 2.1.前端和后端的概念 说明 ...
- 基于UDP的交互的实例
1.实现简单的客户端.服务端聊天交互 问题是:客户端不能单独一直发消息回复.. 服务端: import socket server=socket.socket(socket.AF_INET,socke ...
- Lua学习笔记(一)-----C#和lua的交互
一直以来对Lua热更新技术很感兴趣,在上周开始了对Lua的学习,主要学的是uLua. 直接上干货 准备工作: LuaInterface包括两个核心库一个是LuaInterface.dll,一个是Lua ...
- C语言和Lua的交互
//test.c #include <stdio.h> #include "lua.h" #include "lualib.h" #include ...
- JSON数据格式以及与后台交互数据转换实例
/* 作者:烟大阳仔 时间:20131013 介绍:主要了解一下json的格式,看看数据是怎么存储的 */ <!DOCTYPE html PUBLIC "-//W3C//DTD HTM ...
- spring mvc 和ajax异步交互完整实例
Spring MVC 异步交互demo: 1.jsp页面: <%@ page language="java" contentType="text/html; cha ...
- Lua 服务器与客户端实例(转)
=============================================================== 服务器,main.lua ======================= ...
随机推荐
- 2020Nowcode多校 Round9 B.Groundhog and Apple Tree
题意 给一棵树 初始\(hp=0\) 经过一条边会掉血\(w_{i}\) 第一次到达一个点可以回血\(a_{i}\) 在一个点休息\(1s\)可以回复\(1hp\) 血不能小于\(0\) 每条边最多经 ...
- 2015ACM/ICPC亚洲区沈阳站-重现赛 D - Pagodas
题意:有\(n\)个数,开始给你两个数\(a\)和\(b\),每次找一个没出现过的数\(i\),要求满足\(i=j+k\)或\(i=j-k\),当某个人没有数可以选的时候判他输,问谁赢. 题解:对于\ ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)
JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...
- Dapr微服务应用开发系列2:Hello World与SDK初接触
题记:上篇介绍了Dapr的环境配置,这次我们来动手尝试一下Dapr应用的开发 Hello World Dapr应用的Hello World其实和其他的Hello World一样简单: 首先用你喜欢的语 ...
- windows创建p12格式的ios开发证书的流程
现在做ios开发,原生的开发已经不是第一选择,现在有很多不同的H5开发框架,在性能上都不输原生开发,而UI方便却能做得比原生更炫,比如CSS得灵活度肯定是比原生开发出来得应用更灵活的. 我们在开发IO ...
- 国产网络损伤仪SandStorm -- 只需要上下拖拽能调整链路规则顺序
国产网络损伤仪SandStorm(弱网络测试)可以模拟出带宽限制.时延.时延抖动.丢包.乱序.重复报文.误码.拥塞等网络状况,在实验室条件下准确可靠地测试出网络应用在真实网络环境中的性能,以帮助应用程 ...
- Kubernets二进制安装(8)之部署四层反向代理
四层反向代理集群规划 主机名 角色 IP地址 mfyxw10.mfyxw.com 4层负载均衡(主) 192.168.80.10 mfyxw20.mfyxw.com 4层负载均衡(从) 192.168 ...
- woj1016 cherry blossom woj1017 Billiard ball 几何
title: woj1016 cherry blossom date: 2020-03-18 20:00:00 categories: acm tags: [acm,几何,woj] 几何题,判断给出的 ...
- IFIX 5.9 历史数据 曲线 (非SQL模式)
装完 ifix 5.9 默认是没有Hist 开头的 历史数据源的,没存,至少我装的版本是这样. 那个Historian 也没有安装包,好像还要授权,自己研究不了. 1 先把数据存本地 在你的安装包里 ...
- ADN vs CDN All In One
ADN vs CDN All In One Netlify & JAMstack https://app.netlify.com/teams/xgqfrms/sites ADN Applica ...