Lua脚本实现
2009-8-15 14:10:8
收藏:0
阅读:321
评论:1
我目前正在把 Lua 集成到我的某个应用程序中。目前,我只是使用 C API 和 lua_register
注册函数,但我想要能够将静态和非静态函数指针传递给某些类方法。
我在网上找到了一些库,但由于我只需要它们提供的非常少的功能,所以我想知道是否有一种简单的方法来实现它。
谢谢。
原文链接 https://stackoverflow.com/questions/1281972
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
使用 SWIG 包装 C 库 API
一个复杂的库 API 经常可以使用 SWIG 快速包装(近乎完全地)。在这种情况下使用 SWIG 的一个优点是可以很容易地构建基于 SWIG 的包装器,使得库在 18 种主要语言 中可以使用,包括 Lua、Perl、Python、Ruby 和 Java 等。
如果 Lua 是您首选的(甚至是唯一的)选择,那么我建议您学习使用
luaL_register()
来作为构建 C 语言模块策略的核心。通过这种方式构建模块的一个好处是,您可以在一个命名空间中保留所有函数,而没有额外的开销。您需要编写一个包装器函数,以匹配 Lua C 函数调用约定(就像lua_register()
一样),并从堆栈中获取 Lua 参数,调用包装函数,将任何返回值和输出参数推回到 Lua 堆栈中。在书籍《Programming in Lua》中,可以找到有关如何构建这个函数的概述。第一版的在线副本在第 26 章中讨论了库的创建,但是是为 Lua 5.0 编写的。我强烈建议所有严肃使用 Lua 的人拥有当前版本的《PiL》。不幸的是,在模块(包括 C 和 Lua)动态加载时,Lua 5.1 和 5.0 最不同的地方之一就是
require
。这里是一个在 Lua 5.1 中运行的 C 库的完整(但小型)示例。我们从 C 文件中的包装器实现开始:
#include <lua.h> #include <luaxlib.h> #include <math.h> #undef PI #define PI (3.14159265358979323846) static int l_sin (lua_State *L) { double r = luaL_checknumber(L,1); lua_pushnumber(L, sin(r)); return 1; } static int l_cos (lua_State *L) { double r = luaL_checknumber(L,1); lua_pushnumber(L, cos(r)); return 1; } static const struct luaL_reg smlib [] = { {"sin", l_sin}, {"cos", l_cos}, {NULL, NULL} /* sentinel */ }; int luaopen_sm (lua_State *L) { luaL_openlib(L, "sm", smlib, 0); lua_pushnumber(L,PI); lua_rawset(L,-2,"pi"); return 1; }
需要特别注意的是,唯一需要导出的函数是
luaopen_sm()
,其名称必须对应于将用于require
的模块的名称,以及 DLL 文件的名称。使用该文件编译为名为sm.dll
的 DLL(在类 Unix 系统中可能命名为libsm.so
)后,可以像这样在 Lua 脚本中加载并使用它:require "sm" print(sm.sin(sm.pi/3), sm.cos(sm.pi/3));
这个示例虽然未经测试,但应该可以编译并运行。有关包装来自
math.h
的大多数函数的完整示例,请参见随 Lua 分发的 源代码math
模块。由于这些薄包装器包含大量重复的代码,因此像 SWIG 这样的工具通常可以仅根据每个函数的声明来创建它们。在原则上,包装 C++ 类的方法是类似的。每个可在 Lua 中调用的包装器函数都需要一个可以映射到 C++ 一侧的
this
参数,并且必须作为模块静态函数或静态成员函数实现,也相应地定位目标对象实例以及转换其他参数。SWIG 在构建这种包装器方面特别优秀,并在整个过程中隐藏了很多恶心的细节。