【问题标题】:Instantiating Lua objects through the C API通过 C API 实例化 Lua 对象
【发布时间】:2012-12-20 00:36:39
【问题描述】:

我正在尝试通过 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));
}

我收到以下错误:尝试索引本地“自我”(零值)

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

谢谢!

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

    定义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)。

    【讨论】:

    • a:method(...)总是等价于a.method(self, ...)
    • 更准确地说,function call a:method(params) 总是等价于a.method(a,params) (除了a 只计算一次),function definition function a:method(params) body end 总是等价的到a.method = function(self, params) body end
    • 天哪,我忘记了function。的确。看起来我什至不能再编辑第一条评论了。
    • 我明白为什么对Foo 的调用需要我传递self 但在这个例子中create 真的需要它吗?当我调用它时,它返回给我一个self
    • @Addy:进一步解释,self 没有什么特别之处,除了它是用于由冒号语法引入的隐式参数的名称。您对create 的定义只是声明了一个名为self 的新变量,它隐藏了self 函数参数。
    猜你喜欢
    • 1970-01-01
    • 2018-05-07
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 2014-05-15
    • 1970-01-01
    相关资源
    最近更新 更多