第一版为 Lua 5.0 编写。虽然对于后续版本而言仍具有很大关联性,但也有一些差异。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目。
Lua 编程 | ||
第四部分。C API 第 25 章。扩展您的应用程序 |
Lua 的一大优势在于配置文件可以定义应用程序要调用的函数。例如,您可以编写一个应用程序来绘制函数的图形,并使用 Lua 来定义要绘制的函数。
调用函数的 API 协议很简单:首先,您推送要调用的函数;其次,您推送调用参数;然后,您使用 lua_pcall
执行实际调用;最后,您从堆栈中弹出结果。
作为一个示例,让我们假设我们的配置文件有一个类似于以下内容的函数
function f (x, y) return (x^2 * math.sin(y))/(1 - x) end并且您希望在 C 中计算
z = f(x, y)
,其中 x
和 y
已知。假设您已经打开了 Lua 库并运行了配置文件,则可以将此调用封装在以下 C 函数中
/* call a function `f' defined in Lua */ double f (double x, double y) { double z; /* push functions and arguments */ lua_getglobal(L, "f"); /* function to be called */ lua_pushnumber(L, x); /* push 1st argument */ lua_pushnumber(L, y); /* push 2nd argument */ /* do the call (2 arguments, 1 result) */ if (lua_pcall(L, 2, 1, 0) != 0) error(L, "error running function `f': %s", lua_tostring(L, -1)); /* retrieve result */ if (!lua_isnumber(L, -1)) error(L, "function `f' must return a number"); z = lua_tonumber(L, -1); lua_pop(L, 1); /* pop returned value */ return z; }
您使用要传递的参数数量和想要的结果数量来调用 lua_pcall
。第四个参数表示错误处理函数;我们稍后会讨论它。与 Lua 赋值一样,lua_pcall
会根据您的要求调整实际结果数量,根据需要推送 nil 或丢弃额外值。在推送结果之前,lua_pcall
会从堆栈中移除函数及其参数。如果函数返回多个结果,则首先推送第一个结果;因此,如果有 n 个结果,第一个结果将在索引 -n 处,最后一个结果将在索引 -1 处。
如果在运行 lua_pcall
时出现任何错误,lua_pcall
会返回一个非零值;此外,它还会将错误消息压入堆栈(但仍然会弹出函数及其参数)。然而,在压入消息之前,lua_pcall
会调用错误处理函数(如果有)。要指定错误处理函数,我们使用 lua_pcall
的最后一个参数。零表示没有错误处理函数;也就是说,最终错误消息就是原始消息。否则,该参数应该是错误处理函数在堆栈中的索引。请注意,在这种情况下,必须在要调用的函数及其参数之前将处理程序压入堆栈。
对于常规错误,lua_pcall
返回错误代码 LUA_ERRRUN
。两种特殊类型的错误需要不同的代码,因为它们永远不会运行错误处理程序。第一种是内存分配错误。对于此类错误,lua_pcall
始终返回 LUA_ERRMEM
。第二种是在 Lua 运行错误处理程序本身时发生的错误。在这种情况下,再次调用错误处理程序几乎没有用,因此 lua_pcall
会立即返回代码 LUA_ERRERR
。
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |