Open gh-liu opened 4 months ago
FFI 库允许在 Lua 代码里调用外部 C 函数并使用 C 数据结构 FFI 库很大程度上消除了用 C 编写繁琐的手动 Lua/C 绑定的需要(FFi库会解析C声明,也就是可以直接从C头文件中复制过来)
词汇:
ctype
ffi.typeof()
cdata
ffi.cdef(def)
def 是一个 Lua 字符串,其必须是一系列 C 声明,通过分号隔开,单个声明的分号可以省略。
不支持任何预处理符号,除了#pragma pack。
#pragma pack
ffi.C
默认的 C 库命名空间。
与目标系统上的默认符号或库集绑定。这些符号或库与 C 编译器默认提供的符号或库大致相同,无需指定额外的链接库。
clib = ffi.load(name [,global])
加载按名称指定的动态库,并返回绑定到其符号的新 C 库命名空间。 在 POSIX 系统上,如果 global 为 true,则库符号也会加载到全局命名空间中。
如果 name 是路径,则从此路径加载库,否则,名称将以系统相关的方式规范化,并在动态库的默认搜索路径中搜索。 在 POSIX 系统上,如果名称不包含点,则会附加扩展名.so,此外如有必要,还会在前面添加lib前缀。因此 ffi.load("z") 在默认共享库搜索路径中查找“libz.so”。
.so
lib
-- 创建指定 ct 的 cdata 对象,VLA/VLS 类型需要指定 nelem cdata = ffi.new(ct [,nelem] [,init...]) -- 为给定的 ct 创建一个 ctype 对象 ctype = ffi.typeof(ct) -- 为给定的 ct 创建一个 ctype 对象并将其与元表关联 -- 仅允许结构/联合类型、复数和向量 -- 与元表的关联是永久性的,之后无法更改 ctype = ffi.metatype(ct, metatable) -- 使用 ctype 作为构造函数 cdata = ctype([nelem,] [init...]) -- 为给定的 ct 创建标量 cdata 对象,使用 C 类型转换规则 cdata = ffi.cast(ct, init) -- 将终结器与指针或聚合 cdata 对象关联 cdata = ffi.gc(cdata, finalizer)
size = ffi.sizeof(ct [,nelem]) align = ffi.alignof(ct) ofs [,bpos,bsize] = ffi.offsetof(ct, field) status = ffi.istype(ct, obj)
-- 返回由最后一个 C 函数调用设置的错误号,该错误号指示错误情况 err = ffi.errno([newerr]) -- 从 ptr 指向的数据创建一个内部 Lua 字符串 str = ffi.string(ptr [,len]) -- 将 src 指向的数据复制到 dst ffi.copy(dst, src, [,len]) -- 用 len 个常量字节 c 填充 dst 指向的数据。 ffi.fill(dst, len [,c])
luajit ffi
词汇:
ctype
的值ffi.typeof()
返回的特殊cdata
,调用时以充当cdata
的构造函数声明和访问外部符号
ffi.cdef(def)
def 是一个 Lua 字符串,其必须是一系列 C 声明,通过分号隔开,单个声明的分号可以省略。
不支持任何预处理符号,除了
#pragma pack
。ffi.C
默认的 C 库命名空间。
与目标系统上的默认符号或库集绑定。这些符号或库与 C 编译器默认提供的符号或库大致相同,无需指定额外的链接库。
clib = ffi.load(name [,global])
加载按名称指定的动态库,并返回绑定到其符号的新 C 库命名空间。 在 POSIX 系统上,如果 global 为 true,则库符号也会加载到全局命名空间中。
如果 name 是路径,则从此路径加载库,否则,名称将以系统相关的方式规范化,并在动态库的默认搜索路径中搜索。 在 POSIX 系统上,如果名称不包含点,则会附加扩展名
.so
,此外如有必要,还会在前面添加lib
前缀。因此 ffi.load("z") 在默认共享库搜索路径中查找“libz.so”。创建 cdata 对象
C 类型信息
工具函数
FFI Semantics