当前位置: 首页 > 工具软件 > LuaJIT > 使用案例 >

luajit开发文档wiki中文版(二) LuaJIT 扩展

郦楷
2023-12-01

2022年6月9日09:39:53

luajit开发文档中文版(一)下载和安装

luajit开发文档中文版(二)LuaJIT扩展

luajit开发文档中文版(三)FAQ 常见问题

luajit开发文档wiki中文版(一) 总目录

luajit开发文档wiki中文版(二) LuaJIT 扩展

luajit开发文档wiki中文版(三)性能调优和测试

luajit开发文档wiki中文版(四) LuaJIT 内部结构

luajit开发文档wiki中文版(五) 系统集成

luajit开发文档wiki中文版(六) LuaJIT 开发

可用 FFI 绑定列表

请注意,大多数开发人员更喜欢只绑定到他们实际需要的少数库调用。例如,rmdir()绑定只是与 LuaJIT FFI 的一行。与 eg 的简单绑定zlib只需要两打行,请参阅FFI 教程。你可以在网上找到很多这样的例子。

以下列表仅显示较大或较全面的库绑定:

核心操作系统库

数据库

图形

音频视频

消息和事件

联网

编码和解码

加密货币

压缩

游戏引擎

跨语言 RPC

跨语言桥梁

统一码

杂项

  • ufo:为 OSX/Windows 和其他平台预编译的二进制文件。绑定:Cairo、Pixman、SDL 1.3、zlib、libpng、libbz2、ZeroMQ、Expat、Freetype、GLFW、APR、AntTweakBar、OpenGL、OpenCL。
  • luapower/hunspell : hunspell(拼写检查)
  • luajit-tcc : 微型 C 编译器。
  • luapower/luastate : 绑定到 Lua C API 以创建独立的 Lua 状态
  • luapower/dynasm : 使用Lua 的DynASM
  • luapower/cbframe:低级 FFI 回调帧(解决 FFI ABI 限制的方法)
  • luajit-gmp:GNU 多精度库。
  • lua-clang : C 接口到 Clang 的绑定。

可用软件包列表

由于 Lua 是一种非常简洁的语言,具有最少的预安装库,因此 Lua 程序员可用的大部分功能来自对外部库执行互操作调用。特别是 LuaJIT,为调用外部库提供了极好的支持。如果您想要访问目标系统上的预编译库,那么您需要使用FFI 绑定库。

如果您想要的是 100% 用 Lua 编写的代码,没有额外的库依赖项,那么您可能想要获取此处列出的包之一。

标准是:

  • 100% LuaJIT 代码
  • 不依赖外部库

您的用例是否通过使用本机包而得到极大改进取决于您的标准。一个关键的好处可能只是你不必携带和维护一个单独的库,它是用与 Lua 不同的语言编写的。

编码和解码

加密

  • lrc4 : RC4 流密码

标准功能

  • LAPHLibs:各种函数,包括utf-8、crc、md5、streams、xml
  • LPegLJ:基于 PEG(解析表达式)和简化 RegEx(正则表达式)al la LPeg的字符串模式匹配。
  • luapower/utf8 : utf-8 基础
  • Lua Fun : 为跟踪 JIT 优化的函数式编程库

系统库

数值库

  • Rclient:通过 Rserve 将 LuaJIT 与 R 语言接口

日期时间库

  • 时间:根据公历的日期和期间

数据结构

图形

束包

  • UFO - 包括 OpenGL 和 glu、OpenCL、SDL、ZeroMQ、GLFW

FFI参数化类型

参数化类型是 LuaJIT FFI 的一个特性。它使人们能够动态地指定 FFI C 声明。它对泛型编程很有用,类似于使用C++ 模板Java 泛型的原因。

此功能于 2012 年 6 月推出,在 LuaJIT 2.0.1 及更高版本中可用。

要使用此功能,您可以将字符放在由and$使用的 C 类型声明中。当你使用这个声明时,你会传递参数。这些参数可以是ctype / cdata字符串数字ffi.cdefffi.type

以下是一些示例(单独来看并不是很有趣):

ffi.typeof("$ *", foo_t) ffi.typeof("struct { $ k; $ v; }[?]", foo_t, bar_t) ffi.typeof("uint8_t[$][$]", width, height)

邮件列表中的文档

以下内容发布在 LuaJIT 邮件列表中。

$字符是在 C 类型声明中被参数替换的标记:

  • ctypecdata参数被解释为匿名 typedef。您可以使用它来构造派生类型,例如 ffi.typeof("$*", ct)是指向 的指针ct,或者"$[10]"是 10 元素数组。与简单的字符串连接不同,这适用于所有情况(例如指向函数指针的指针)。

  • 字符串参数被视为标识符或关键字,除了字符串不会再次解析或拆分为单词(这不是简单的文本替换)。您可以将其用于字段名称、函数名称、参数名称等。

    [我正在考虑是否应该删除关键字并在字符串上键入查找。这将允许您对字段使用任意名称,即使它们与关键字或 typedef 冲突。我可能会在编写文档之前更改它。]

  • 数字参数被视为整数。您可以使用它来构造固定大小的数组。在某些情况下,您可能更喜欢 VLA。它也适用于多维类型。例如:

local matrix_t = ffi.typeof("uint8_t[$][$]", width, height) ... local m = matrix_t()

仅解析参数化类型ffi.typeof()ffi.cdef()其他函数,例如ffi.new(),不这样做,因为它们已经接受了其他参数(例如初始化器)。我想混合两种论点会太混乱。

无论如何,参数化类型是一个很好的工具,但你会想谨慎使用它!

您会想到在 C++ 中使用模板的典型场景:例如,构建任意类型的堆栈或队列。这些都需要创建一个元素类型的数组,现在真的很容易做到。[贾斯汀的用例]

另一个例子是匿名结构的派生类型。这避免了结构命名空间的污染。[亨克的用例]

堆栈示例

Mike在 LuaJIT 邮件列表上发布了这个示例:

local ffi = require("ffi") local function stack_iter(stack) local top = stack.top if top > 0 then stack.top = top-1 return stack.slot[top-1] end end local stack_mt = { __new = function(tp, max) return ffi.new(tp, max, 0, max) end, __index = { push = function(stack, val) local top = stack.top if top >= stack.max then error("stack overflow") end stack.top = top + 1 stack.slot[top] = val end, pop = function(stack) local top = stack.top if top <= 0 then error("stack underflow") end stack.top = top-1 return stack.slot[top-1] end, iter = function(stack) return stack_iter, stack end, } } local function makestack(ct) local tp = ffi.typeof("struct { int top, max; $ slot[?]; }", ct) return ffi.metatype(tp, stack_mt) end local stack_t = makestack(ffi.typeof("double")) local stack = stack_t(100) for i=1,100 do stack:push(i) end for x in stack:iter() do io.write(x, " ") end io.write("
 类似资料: