Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating Lua objects through the C API

Tags:

c++

lua

I am trying to do some OO functionality in Lua via the C API. In my Lua script I have the following:

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()

If I run this from the command line, it works fine and I see the following output:

creating
baseUrl: http://www.google.com

Now, if I comment out the last two lines and try the following through the 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
}

This works. I see "creating" in my standard output as expected. As I understand it, the new Parser object is now on top of the stack. If I them immediately try the following:

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

I get the following error: attempt to index local 'self' (a nil value)

Can anyone tell me what I'm doing wrong and how to get the function to run as expected?

Thank you!

like image 406
Addy Avatar asked Mar 10 '26 23:03

Addy


1 Answers

The definition function Parser:Foo() ... end is equivalent to:

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

That is -- Foo is a function that takes one argument. When you call lua_pcall(L, 0, 0, 0) you are passing 0 arguments. Change it to lua_pcall(L, 1, 0, 0) and everything should work. (You will have to also change the pcall to create to correctly pass 2 arguments rather than 1).

like image 114
Mankarse Avatar answered Mar 13 '26 12:03

Mankarse



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!