Lua与C交互学习笔记
Lua与C交互是通过虚拟栈实现的
在C中调用Lua
方法一
--hello.lua
str = "Hello, Lua !"
table = {name = "cjj", id = 123456}
function myFunc(param1, param2)
return value1,value2
end
#include <stdio.h>
#include "../include/lauxlib.h"
lua_State *load_lua(char *filename) {
lua_State *L = luaL_newstate();//创建虚拟栈
luaL_openlibs(L);//打开lua文件
//加载脚本并运行
if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)) {
printf("load Lua script failed: %s\n", lua_tostring(L, -1));
return NULL;
}
return L;
}
int main(int argc, const char *argv[]) {
char* lua_filename = ".\\hello.lua";//.lua路径
lua_State *L = load_lua(lua_filename);//加载lua文件
if (NULL == L) {
return -1;
}
//读取变量
lua_getglobal(L, "str");//将str变量压入栈顶
printf("%s\n", lua_tostring(L, -1));
//读取table
lua_getglobal(L, "table");//将table压入栈顶
lua_getfield(L, -1, "name");//将索引-1对应的table中的name变量压入栈顶
printf("%s\n", lua_tostring(L, -1));
//调用函数
lua_getglobal(L, "myFunc"); //读取函数到栈顶
lua_pushnumber(L, param1); //压入参数
lua_pushnumber(L, param2);
//参数依次为虚拟栈,压入参数数,返回值数,错误回调函数(为0时将错误信息压入栈顶)
//调用函数成功会弹出参数与函数并压入返回值
if (lua_pcall(L, 2, 2, 0) != 0) {
printf("lua_pcall failed: %s\n", lua_tostring(L, -1));
return -1;
}
int value2 = lua_tonumber(L, -1);
printf("%d\n", value2);
int value1 = lua_tonumber(L, -2);
printf("%d\n", value1);
lua_close(L);
return 0;
}
栈中的情况如下表所示
索引 | 类型 | 值 |
---|---|---|
5 | (var) | value2 |
4 | (var) | value1 |
3 | string | cjj |
2 | table | table |
1 | string | Hello, Lua ! |
方法二
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/* 指向Lua解释器的指针 */
lua_State* L;
static int myFunc(lua_State *L)
{
/* 返回返回值的个数 */
return n;
}
int main(int argc, char *argv[])
{
/* 初始化Lua */
L = lua_open();
/* 载入Lua基本库 */
luaL_openlibs(L);
/* 注册函数 */
lua_register(L, "myFunc", myFunc);
/* 运行脚本 */
luaL_dofile(L, "test.lua");
/* 清除Lua */
lua_close(L);
return 0;
}
--test.lua
value1,value2... = myFunc(param1,param2...)
在Lua中调用C
Lua通过调用动态库(.dll)方法调用C
创建动态库
以VS2017为例

//mylualib.h
#pragma once
//加入lua库
#include "..\include\lua.h"
#include "..\include\lualib.h"
#include "..\include\lauxlib.h"
__declspec(dllexport) int luaopen_myLualib(lua_State *L);//定义导出函数
//myLualib.c
#include <stdio.h>
#include "myLualib.h"
static int myFunc1(lua_State *L)
{
/*****************************************
常用的函数
lua_gettop(L)得到参数个数
lua_tonumber(L, 1)获取数值型参数param1
lua_tonumber(L, 2)获取数值型参数param2
...
lua_pushnumber(L, value1)返回值value1
lua_pushnumber(L, value2)返回值value2
...
****************************************/
//函数体
return n; //返回值个数
}
static int myFunc2(lua_State* L)
{
return n;
}
static const struct luaL_Reg myLib[] =
{
{"myFunc1", myFunc1},
{"myFunc2", myFunc2},
{NULL, NULL} //数组中最后一对必须是{NULL, NULL},用来表示结束
};
int luaopen_myLualib(lua_State *L)
{
luaL_register(L, "moduleName", myLib);
return 1; // 把myLib表压入了栈中,所以就需要返回1
}
Lua中加载.dll
dllPath=".\\Dll1.dll"--.dll路径
outFuncName="luaopen_mLualib"--导出函数名
local testlib = package.loadlib(dllPath,outFuncName);
if(testlib)then
testlib(); --打开模块
value1,value2... = moduleName.myFunc1(param1,param2...) -- 参数对应堆栈中的数据
moduleName.myFunc2() --调用myFunc2()
else
print("error")-- Error
end
网友评论