risc-v中文社区

 找回密码
 立即注册
查看: 2799|回复: 0

Lua源码分析 - 实战篇 - Lua的API使用(19)

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-20 16:02:14 | 显示全部楼层 |阅读模式
目录

一、实战篇 - Lua的安装和Makefile

二、实战篇 - Lua的API使用

三、实战篇 - C语言中实现动态调用Lua

一、实战篇 - Lua的安装和Makefile
前面的篇章,我们详细的介绍了整个Lua语言的架构和实现原理。

Lua是一门C语言编写的脚本语言,非常的轻巧,大部分情况下Lua的使用场景是作为宿主语言存在。web脚本、游戏脚本、物联网等场景。通俗点讲,你可以将Lua语言作为一个类库,加载到你的项目中,利用Lua提供的API函数以及Lua语言的动态加载特性,可以做一些动态化管理配置的事情。

Lua安装

使用curl下载Lua的源码包,并解压
然后通过Make命令,执行安装。执行安装之前,可以针对不同的系统进行测试
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz
tar zxf lua-5.3.5.tar.gz
cd lua-5.3.5
make linux test
make install
Lua安装完成后,我们可以通过lua -v 命令,查看lua是否安装成功。

****:Togo zhuli$ lua -v
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
查看安装信息

Lua在Linux系统下默认是标准的安装。编译成功后,二进制可执行文件以及链接库这些都会放进/usr/local/目录下。

你也可以执行make echo 命令,查看Lua的安装信息。

*****:lua-5.3.5 zhuli$ make echo
PLAT= none
CC= gcc -std=gnu99
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2  
LDFLAGS=
LIBS= -lm  
AR= ar rcu
RANLIB= ranlib
RM= rm -f
PLAT= none
V= 5.3
R= 5.3.4
TO_BIN= lua luac
TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
TO_LIB= liblua.a
TO_MAN= lua.1 luac.1
INSTALL_TOP= /usr/local
INSTALL_BIN= /usr/local/bin
INSTALL_INC= /usr/local/include
INSTALL_LIB= /usr/local/lib
INSTALL_MAN= /usr/local/man/man1
INSTALL_LMOD= /usr/local/share/lua/5.3
INSTALL_CMOD= /usr/local/lib/lua/5.3
INSTALL_EXEC= install -p -m 0755
INSTALL_DATA= install -p -m 0644
卸载Lua

我们在Lua源码文件夹下执行sudo make uninstall,就会删除Lua程序

***:lua-5.3.5 zhuli$ sudo make uninstall
Password:
cd src && cd /usr/local/bin && rm -f lua luac
cd src && cd /usr/local/include && rm -f lua.h luaconf.h lualib.h lauxlib.h lua.hpp
cd src && cd /usr/local/lib && rm -f liblua.a
cd doc && cd /usr/local/man/man1 && rm -f lua.1 luac.1
重新编译Lua

如果你不修改Lua,则不需要重新编辑。如果修改了源码,我们需要进行重新编辑,则需要执行 make macosx clean命令,清楚编译的so文件。然后执行make macosx,进行编译。执行make install 进行安装。

***:lua-5.3.5 zhuli$ make macosx clean
cd src && /Library/Developer/CommandLineTools/usr/bin/make macosx
/Library/Developer/CommandLineTools/usr/bin/make all SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
make[2]: Nothing to be done for `all'.
cd src && /Library/Developer/CommandLineTools/usr/bin/make clean
rm -f liblua.a lua luac lapi.o lcode.o lctype.o ldebug.o ldo.o
ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o
lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o
lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o
lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o lmylib.o  lua.o luac.o
Makefile文件

如果要了解Makefile文件的规则,可以看我之前的文章:《Linux c 开发 - Makefile工具》

如果要了解gcc编译的规则,则可以看我之前的文章:《Linux c 开发 - gcc》

Lua工程中,有两个Makefile文件:

外层的Makefile文件,主要定义了make install 、make等操作命令
src/Makefile文件,主要定义了项目编译的规则

二、实战篇 - Lua的API使用
Lua作为宿主语言,可以作为一个扩展库,加载进我们的工程中。Lua在lapi.c文件中,提供了丰富的API(主要以栈操作为主),提供给我们进行Lua语言在操作。

在《Lua源码分析 - 栈结构篇 - 栈操作函数的实现(04)》文章中,我们介绍了栈操作的API函数。

我们编写一个main.c,在main.c中需要加入lua.h、lualib.h、lauxlib.h 头文件。

程序:主要是建立一个Lua的栈,然后在栈上设置数据,继续从栈上获取数据和出栈操作,最后关闭栈。

    #include <stdio.h>
    #include <stdlib.h>
    #include  <math.h>
    #include  <lua.h>
    #include  <lualib.h>
    #include <lauxlib.h>



    int main() {

        printf("----------Hello Lua API------------\n");

        /* 初始化一个栈 */
        lua_State *L = luaL_newstate();
        luaL_openlibs(L);
        lua_pushstring(L, "Lua API");
        lua_pushstring(L, "Hello Lua");

        /* 栈顶入栈两个int类型数据 */
        lua_pushinteger(L, 170); //身高
        lua_pushinteger(L, 35); //年龄

        /* 栈顶入栈1个字符串类型数字*/
        lua_pushstring(L, "zhuli"); //姓名

        /* 获取栈个数 */
        int size = lua_gettop(L);
        printf("栈个数:%i\n", size);

        /* 获取数据 */
        const char* name = lua_tolstring(L, -1, NULL);
        printf("姓名:%s\n", name);

        int age = (int) lua_tointegerx(L, -2, NULL);
        printf("年龄:%d\n", age);

        int height = (int) lua_tointegerx(L, -3, NULL);
        printf("身高:%d\n", height);

        /* 弹出栈顶3个数据 */
        lua_pop(L, 3);

        /* 获取栈个数 */
        int size2 = lua_gettop(L);
        printf("POP 弹出3个后,栈个数:%i\n", size2);

        /* 获取字符串 */
        const char* str = lua_tolstring(L, -1, NULL);
        const char* str2 = lua_tolstring(L, -2, NULL);
        printf("字符串:%s\n字符串:%s\n", str, str2);

        /* 关闭栈 */
        lua_close(L);
        printf("----------Hello Lua API Close------------\n");

        return 0;
    }
将main.c文件编译成二进制可执行文件。其中编译参数中,我们需要带上-l lua,将lua库作为静态库编译到我们的工程中去。

我们执行./main文件后,发现程序正常操作,我们调用Lua的API成功了。

gcc编译不熟悉的,可以继续看我的文章:《Linux c 开发 - gcc》

-llua  -lm -ldl :加载lua库、数据库和dl库

***:Togo zhuli$ gcc main.c -o main -llua  -lm -ldl
***:Togo zhuli$ ./main
----------Hello Lua API------------
栈个数:5
姓名:zhuli
年龄:35
身高:170
POP 弹出3个后,栈个数:2
字符串:Hello Lua
字符串:Lua API
----------Hello Lua API Close------------
三、实战篇 - C语言中实现动态调用Lua
上面我们讲到了Lua的API使用和入栈出栈操作。但是如何来实现在我们C语言里面,动态加载Lua脚本语言呢,实现Lua的动态化配置能力。这里有两种方案:

文件脚本加载方式:我们将Lua语言编写成脚本文件,通过luaL_loadfile函数,将文件加载进来;然后通过lua_pcall函数,执行脚本文件
字符串脚本加载方式:通过luaL_dostring函数,直接执行字符串形式的Lua脚本。这种方式,脚本就可以作为一种变量形式进行变更。
    #include <stdio.h>
    #include <stdlib.h>
    #include  <math.h>
    #include  <lua.h>
    #include  <lualib.h>
    #include <lauxlib.h>


    int main() {

        printf("----------Hello Lua API------------\n");

        /* 初始化一个栈 */
        lua_State *L = luaL_newstate();
        luaL_openlibs(L);
        lua_pushstring(L, "Lua API");
        lua_pushstring(L, "Hello Lua");

        int size = lua_gettop(L);
        printf("栈个数:%i\n", size);

        /* 文件加载方式 */
        luaL_loadfile(L, "test.lua"); //加载文件
        int size2 = lua_gettop(L);
        printf("加载文件后,栈个数:%i\n", size2);

        lua_pcall(L, 0, 0, 0); //执行文件

        /* 加载字符串形式的Lua脚本 */
        luaL_dostring(L, "print('luaL_dostring:执行字符串形式的Lua脚本')");

        /* 关闭栈 */
        lua_close(L);
        printf("----------Hello Lua API Close------------\n");

        return 0;
    }


//test.lua
print("luaL_loadfile:执行文件加载的Lua脚本!");
然后编译执行,这里面就会发现,Lua文件加载后,作为一个值进行了入栈操作(栈的个数+1)。

***:Togo zhuli$ ./main
----------Hello Lua API------------
栈个数:2
加载文件后,栈个数:3
luaL_loadfile:执行文件加载的Lua脚本!
luaL_dostring:执行字符串形式的Lua脚本
----------Hello Lua API Close------------

————————————————
版权声明:本文为CSDN博主「老码农zhuli」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/initphp/article/details/105436044

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-24 16:29 , Processed in 0.042164 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表