通过C API实例化Lua对象

时间:2012-12-19 15:58:46

标签: c++ lua

我正在尝试通过C API在Lua中执行一些OO功能。在我的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
}

这很有效。我按预期在标准输出中看到“创建”。据我了解,新的 Parser 对象现在位于堆栈顶部。如果我他们立即尝试以下:

lua_getfield(L, -1, "Foo");
if (lua_pcall(L, 0, 0, 0) != 0)
{
  logger()->error("-- %1", lua_tostring(L, -1));
}

我收到以下错误: 尝试索引本地'self'(零值)

有谁能告诉我我做错了什么以及如何让函数按预期运行?

谢谢!

1 个答案:

答案 0 :(得分:2)

定义function Parser:Foo() ... end相当于:

Parser.Foo = function(self)
    print ("baseUrl: " .. self.baseUrl)
end

那是 - Foo是一个带有一个参数的函数。当您致电lua_pcall(L, 0, 0, 0)时,您正在传递0个参数。将其更改为lua_pcall(L, 1, 0, 0),一切都应该有效。 (您还必须将pcall更改为create以正确传递2个参数而不是1。)