0Pricing
Lua Academy · 课时

通过 FFI 调用 C 函数

从 Lua 调用 libc 和自定义共享库函数,实现零额外开销。

通过 FFI 调用 C 函数 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

直接调用 C 函数

使用 ffi.cdef 声明后,可以通过库对象像调用 Lua 函数一样调用 C 函数。参数和返回值会自动转换。

local ffi = require("ffi")
ffi.cdef[[ double sin(double x); ]]
local m = ffi.load("m")
print(m.sin(math.pi / 2))  -- 1.0

类型转换

Lua 数字默认会转换为 C double。FFI 会自动将其转换为声明的 C 参数类型。布尔值会转换为 0/1。字符串会转换为 const char*。

调用 printf

printf 是可变参数 C 函数。请通过 ffi.C.printf,并传入格式字符串和参数来调用它。

ffi.cdef[[ int printf(const char *fmt, ...); ]]
ffi.C.printf("Sum: %d\n", 42)

处理返回值

C 返回值会自动转换为 Lua 类型。整数会转换为 Lua 数字,char* 会转换为轻量用户数据(使用 ffi.string 进行转换)。

ffi.cdef[[ char *getenv(const char *name); ]]
local ptr = ffi.C.getenv("HOME")
if ptr ~= nil then
  print(ffi.string(ptr))
end

ffi.string

ffi.string(ptr, len) 会将 char* 指针转换为 Lua 字符串。不提供 len 时,它会一直读取到空字节。

错误处理

C 函数会返回错误代码或设置 errno。请显式检查返回值。通过 ffi.errno() 访问 errno。

ffi.cdef[[ int open(const char *path, int flags); ]]
local fd = ffi.C.open("missing.txt", 0)
if fd < 0 then
  print("Error:", ffi.errno())
end

结构体参数

可以按值或按指针传递 C 结构体。使用 ffi.new 创建它们。

ffi.cdef[[
  typedef struct { int x, y; } Point;
  void printPoint(Point p);
]]
local p = ffi.new("Point", {x=3, y=4})
lib.printPoint(p)

指针参数

对于通过指针参数返回多个值的函数,请传入输出指针。

ffi.cdef[[
  void minmax(double *arr, int n, double *min, double *max);
]]
local arr = ffi.new("double[5]", {5,2,8,1,9})
local mn, mx = ffi.new("double[1]"), ffi.new("double[1]")
lib.minmax(arr, 5, mn, mx)
print(mn[0], mx[0])

FFI 调用性能

调用 C 函数的 FFI 开销接近于零,速度远快于通过传统 C API 进行的 Lua 到 C 调用。JIT 通常可以将整个调用完全内联。

可变参数函数

可变参数 C 函数(...)必须使用正确的类型调用。如有需要,请传入显式类型转换,以避免歧义。

ffi.C.printf("%d %f\n", ffi.cast("int", 42), ffi.cast("double", 3.14))

安全实践

始终检查指针返回值是否为 NULL。绝不要传递已释放或超出作用域的指针。使用 ffi.gc 为 C 分配的内存附加终结器。

FFI 调用问题

FFI 如何将 Lua 字符串转换为 C 的 const char*?

回顾:通过 FFI 调用 C

像调用 Lua 函数一样,通过库对象调用 C 函数。FFI 会处理类型转换。对于 char* 返回值,使用 ffi.string;对于错误,使用 ffi.errno();对于结构体或数组参数,使用 ffi.new。

常见问题解答

「通过 FFI 调用 C 函数」课时是免费的吗?

是的 — 「通过 FFI 调用 C 函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「通过 FFI 调用 C 函数」这节课中我会学到什么?

从 Lua 调用 libc 和自定义共享库函数,实现零额外开销。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「通过 FFI 调用 C 函数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. FFI 基础:ffi.cdef 和 ffi.load
  2. 通过 FFI 调用 C 函数
  3. FFI 中的指针、结构体和数组
  4. 回调:将 Lua 函数传递给 C
← 返回 Lua Academy