我正在尝试通过C API在Lua中实现一些面向对象的功能。在我的Lua脚本中,我有以下内容:
Parser = {}
Parser.__index = Parser
function Parser:create(url)
local self = {}
print ("creating")
self.baseUrl = url
setmetatable(self, Parser)
return self
end
function Parser:Foo()
print ("baseUrl: " .. self.baseUrl)
end
p = Parser:create("http://www.google.com")
p:Foo()
如果我从命令行运行它,它能正常工作并显示以下输出:
creating
baseUrl: http://www.google.com
现在,如果我注释掉最后两行并尝试通过C API执行以下操作
// <load the state and lua file>
lua_getglobal(L, "Parser");
lua_getfield(L, -1, "create");
lua_pushstring(L, "http://www.google.com");
if (lua_pcall(L, 1, 1, 0) != 0)
{
// handle error
}
这个可行。我在标准输出中看到了预期的“creating”。据我所知,新的解析器对象现在位于堆栈的顶部。如果我立即尝试以下操作:
lua_getfield(L, -1, "Foo");
if (lua_pcall(L, 0, 0, 0) != 0)
{
logger()->error("-- %1", lua_tostring(L, -1));
}
我看到如下错误信息:尝试对本地变量'self'进行索引(一个空值) 请问有人能告诉我我做错了什么,以及如何使函数按预期运行吗?
谢谢!
a:method(...)
总是等价于a.method(self, ...)
。 - user308323a:method(params)
总是等价于a.method(a,params)
(除了a
只被计算一次),而 函数定义function a:method(params) body end
总是等价于a.method = function(self, params) body end
。 - Mankarsefunction
。看来我甚至不能再编辑第一个评论了。 - user308323Foo
需要传递self
,但在这个例子中,create
是否真的需要它呢?当我调用它时,它会返回一个self
。 - Addycreate
是一个接受两个参数--self
和url
的函数。如果你想让它成为一个只接受一个参数的函数,在定义/使用时不要使用冒号语法(也就是,将其定义为Parser.create = function(url) ... end
)。 - Mankarseself
没有什么特别之处。你对create
的定义只是声明了一个新变量叫做self
,这个变量掩盖了self
函数参数的含义。 - Mankarse