当前位置: 首页 > news >正文

C和lua的互相调用

上代码,码农都喜欢上代码:

下面是main.c:

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

void init_lua(lua_State* L)
{
	luaL_openlibs(L);
	luaopen_base(L);
	luaopen_table(L);
	luaopen_string(L);
	luaopen_math(L);
}

int c_add(lua_State* L)
{
	int a = lua_tonumber(L, -2);
	int b = lua_tonumber(L, -1);
	int c = a + b;
	lua_pushnumber(L, c);
	return 1;
}

int c_step(lua_State* L)
{
	int a = lua_tonumber(L, -1);
	int c = a + 1;
	lua_pushnumber(L, c);
	return 1;
}

luaL_Reg mylib[] = 
{
	{"c_add", c_add},
	{"c_step", c_step},
	{NULL, NULL}
};

int main()
{
	lua_State *L = lua_open();
	init_lua(L);

	if (luaL_loadfile(L, "test.lua") != 0) {
		printf("fail to load\n");
		return 0;
	}

	//everything in lua is variable (including functions), so we need to init them.
	if (lua_pcall(L, 0, 0, 0) != 0) {
		printf("fail to run lua: %s\n", lua_tostring(L, -1));
		return 0;
	}

	//prepare additional functions for lua to call
	luaL_register(L, "mylib", mylib);
	
	//c call lua
	lua_getglobal(L, "l_ff");
	lua_pushnumber(L, 2);
	lua_pushnumber(L, 3);
	if (lua_pcall(L, 2, 1, 0) != 0) {
		printf("fail to call func: %s\n", lua_tostring(L, -1));
		return 0;
	}
	int res = lua_tonumber(L, -1);
	lua_pop(L, 1);

	printf("in c: %d\n", res);

	lua_close(L);

	return 0;
}

下面是test.lua:

function l_ff(a, b)
	local c = mylib.c_add(a, b) + 1
	print ("in lua1: ", c)
	local d = mylib.c_step(c)
	print ("in lua2: ", d)
	return d
end

说明

这些api的名字很怪异,常常没法从名字知道这个函数是做什么的。

lua_getglobal是从lua脚本里面取一个全局变量放到堆栈上(c和lua之间是通过虚拟的堆栈来互相沟通的)。

lua_pushnumber是把一个数字放到堆栈上。

lua_pcall是从当前堆栈进行函数调用。

lua_tonumber这个是把堆栈中的某个值作为int取出来(因为l_ff有返回值,因此堆栈最顶上就是函数的返回值

在函数c_add里面,lua_pushnumber才是lua调用的返回值(在lua里面,同样是把把栈最顶上的位置当作返回值


转载于:https://www.cnblogs.com/hehe520/archive/2012/08/06/6330374.html

相关文章:

  • Win8 RTM 安装到 UEFI PC
  • 做好一个team leader的几点看法
  • 招聘信息NO.5
  • 基于maven和hudson打造持续集成环境
  • 网络字节流数据解析组件的设计与实现--Circular Buffer(Ring Buffer)
  • 小工具 cl-launch , 创建 lisp 执行脚本
  • 从“青年创业基金”说起
  • 云服务系列:Windows Azure SDK for .NET(2012 年 6 月发布的版本)的最新消息
  • vim 键盘图
  • VC++实现感染文件式加载DLL文件
  • pthread_join函数及linux线程
  • hdu 3535 AreYouBusy(三种背包)
  • Linux下的多线程编程
  • yum 删除已安装的软件
  • LinuxThread VS NPTL
  • 2018一半小结一波
  • Android组件 - 收藏集 - 掘金
  • Elasticsearch 参考指南(升级前重新索引)
  • Github访问慢解决办法
  • Invalidate和postInvalidate的区别
  • JS+CSS实现数字滚动
  • nginx 负载服务器优化
  • PHP 的 SAPI 是个什么东西
  • spring cloud gateway 源码解析(4)跨域问题处理
  • 测试如何在敏捷团队中工作?
  • 构建二叉树进行数值数组的去重及优化
  • 基于webpack 的 vue 多页架构
  • 开发基于以太坊智能合约的DApp
  • 力扣(LeetCode)56
  • 前嗅ForeSpider中数据浏览界面介绍
  • 人脸识别最新开发经验demo
  • 一天一个设计模式之JS实现——适配器模式
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • #{} 和 ${}区别
  • ( 10 )MySQL中的外键
  • (poj1.3.2)1791(构造法模拟)
  • (rabbitmq的高级特性)消息可靠性
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (理论篇)httpmoudle和httphandler一览
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (一)UDP基本编程步骤
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)为C# Windows服务添加安装程序
  • (转)原始图像数据和PDF中的图像数据
  • ***通过什么方式***网吧
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET gRPC 和RESTful简单对比
  • .NET NPOI导出Excel详解
  • .net 无限分类
  • .NET和.COM和.CN域名区别
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理