Lua的使用方法在网上资料说多不多说少不少,比起其他语言,Lua遇到的很多问题都不一定能找到解决的方法,因此使用和学习这门语言,真的需要积累,由于最近使用了相关的东西,因此趁这个机会整理一下。
Lua5.3——C API函数Lua实战笔记第4篇 NotePad++ 运行Lua脚本Lua和C++交互总结
首先需要安装Nopad++以及对应的lua插件,有了lua插件其实nopad++就可以执行lua程序。
这步骤和创建一个dll库是类似的,唯一不同的是,对创建对Lua使用的api不需要用到VC++自己创建的文件,因此建立一个空的工程即可。
针对lua和C/C++的交互,是需要使用lua的库文件的,调用Lua的库文件接口,才可以以lua的方式,把接口压到栈里面,然后在lua中才可以调用接口。 需要注意的是lua的版本,最好和nopad++插件中的lua脚本相同,否则容易出现一些规则冲突之类的错误。lua5.3.5库文件lua官网库文件
将下载好的lua库文件导入到工程的头文件和源文件中,然后将lua.c和luac.c去掉。创建一个头文件,进行以下声明:
#pragma once
extern "C"{
#include "../src/lua.h"//指定正确的路径
#include "../src/lualib.h"
#include "../src/lauxlib.h"
}
#ifndef LUA_API
#define LUA_API extern "C" __declspec(dllexport)
#endif
LUA_API int luaopen_LuaLibrary(lua_State *L);//定义导出函数
由于lua的参数取值是以压栈的形式传递,因此,获取lua的参数也需要通过出栈来来获取,下面以简单sum函数为例子:
static int sum(int x, int y)
{
return x + y;
}
static int lua_sum(lua_State* L)
{
int x = lua_tointeger(L, -1);
int y = lua_tointeger(L, -2);
int result = sum(x, y);
lua_pushinteger(L, result);
return 1;
}
lua_State就是L的一个栈,传入的参数均由上往下进行排列,-1永远为栈顶,往栈底递减,1永远为栈底,往栈顶递增,遵循先入先出原则。
static const luaL_Reg lua_xk_lib[] =
{
{ "sum",lua_sum},
{ NULL,NULL }
};
声明了函数之后,需要把函数添加如注册列表,在后面Luaopen_函数中需要将注册列表添加到Lua的注册表中。注意,注册表永远以{NULL,NULL}结尾。
int luaopen_LuaLibrary(lua_State* L)
//luaopen_模块名,用于lua外部调用模块,
//注意与生成的库文件名最好相同
{
lua_newtable(L);
luaL_setfuncs(L, lua_xk_lib, 0);
return 1;
}
将注册表注册到lua的函数注册表内,需要注意的是,在lua5.1中,很多人使用luaL_resiger()函数进行注册,在Lua5.2以后的版本这个函数已经被取消了,需要用另一种方法来注册。
LIBRARY LuaLibrary
; LuaLibrary 将成为生成的dll的名称
DESCRIPTION 'AllenPocket test'
EXPORTS
luaopen_LuaLibrary @3
; 这个名称即为函数的实际导出名称 @1为函数的导出编号
和dll库有点不一样,对Lua提供接口必须有这个声明,否则会找不到文件和接口。
package.path = "C:\\Users\\86137\\Desktop\\Demo\\test\\?.dll"
local m = require("LuaLibrary")
print(m.sum(13,1))
在lua中加载外部脚本以及库都使用require()函数,如果不是放在nopad++的地址中,则需要使用package.path添加文件路径,如果是脚本的话则后面修改为?.lua
调用成功的话如下: