How to "call" a function from a Lua table in C++

Asked

Viewed 850 times

6

I’m trying to "call" a function of a table written in Lua. The problem is that I’m not managing to pass three arguments to this function.

When I pass the arguments, it’s as if the Lua skip the first argument and continue from the second. Below an excerpt of the code.

// C++
// Função responsável por chamar a função do script
int CPP_get(lua_State* ls)
{
    lua_getfield(ls, LUA_GLOBALSINDEX, "vec"); // Coloca vec na pilha
    lua_getfield(ls, -1, "func"); // coloca a função func na pilha
    lua_remove(ls, -2); // Remove vec da pilha
    dumpStack(ls); // Mostra a pilha

    lua_pushnumber(ls, 2.0f); // Primeiro argumento
    lua_pushnumber(ls, 4.0f); // Segundo argumento
    lua_pushnumber(ls, 8.0f); // Terceiro argumento

    dumpStack(ls); // Mostra a pilha
    std::cout << "\n";

    lua_pcall(ls, 3, 1, 0); // Chama a função

    return 1;
}


-- Lua
-- Table
vec = {}
vec.__index = vec

-- Função a ser chamada
function vec:func(x, y, z)
    print("vec:func:", x, y, z)
    return "return: OK"
end

-- Chamando a função
print("CPP.get:", CPP.get())


The function dumpStack, is to show the current "stack" elements. Below is a print of how the "stack" looks. At the end of the run it only passes the second argument on.

Imagen

1 answer

5


Its function actually has 4 arguments. The code

function vec:func(x, y, z)
  print("vec:func:", x, y, z)
  return "return: OK"
end

is syntactic sugar for

vec.func = function(self, x, y, z)
  print("vec:func:", x, y, z)
  return "return: OK"
end

There are two things you can do: if your function doesn’t need the self, you can make it only receive 3 arguments even:

vec.func = function(x, y, z) ... end
-- OU
function vec.func(x,y,z) ... end

alternatively, you can pass your C++ code vec as the first argument of the function. In your case, you can do this by changing the positions of vec and func in the stack instead of removing vec.

// C++
// Função responsável por chamar a função do script
int CPP_get(lua_State* ls)
{
    lua_getfield(ls, LUA_GLOBALSINDEX, "vec"); // Coloca vec na pilha
    lua_getfield(ls, -1, "func"); // coloca a função func na pilha

    lua_insert(L, -2);        // Troca os dois elementos no topo da pilha de posição
    lua_pushnumber(ls, 2.0f); // Primeiro argumento  (segundo, contando com o self)
    lua_pushnumber(ls, 4.0f); // Segundo argumento   (terceiro, contando com o self)
    lua_pushnumber(ls, 8.0f); // Terceiro argumento  (quarto, contando com o self)

    lua_pcall(ls, 4, 1, 0); // Chama a função  //4 argumentos!

    return 1;
}
  • Thank you very much , it is similar to Python. But I was left with another question. You can tell me if there is any difference between . or : ?. Is there any way to make the "programmer" use only one method?. I use . in modules, and : in table methods/"classes" (In my opinion it is more organized).

  • 2

    The difference between Lua and Python is that there are only functions and the : is 100% syntactic sugar (you can read more details in manual or programmiing in lua). If you want vc can translate all : for ., but method calls become very boring to write (obj.method(obj, 17) vs obj:method(17)). As for a recommendation, use self methods for instance methods and self-less functions for static methods in your class.

  • Syntactic sugar? what is this?

  • Syntactic sugar is a name that we use to describe a programming language functionality can be seen as just an abbreviation. Any program using sugar can be rewritten using only more basic operations. For example, in the language C the operator += can be seen as a syntactic sugar. Any use of a += b can be rewritten as a = a + b.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.