lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2009/12/3 Sebastian Wolff <sw@allmech.tuwien.ac.at>:
>> Your new metamethods are closures, and as such they have an
>> environment, and upvalues, even if implemented in C. Therefore you can
>> save a reference to the previous metamethod in one of these places.
>
> The thing is that I do not have any idea how to get the function pointer to
> the old __index function from Lua. The metatable I am referring to has been
> created using some cryptic wrapper code. The object is some userdata. In
> order to get the __index method handle I would need to create the userdata,
> push it to the stack, then get its metatable and push it to the stack. Then
> I would need to get the field __index of this metatable and somehow obtain
> the function pointer. But since I have no idea how to create the userdata
> (without digging into the wrapper code) I can only get it by calling a Lua
> script. However, I could pass Lua code that creates local variables. But
> afterwards examining the variables is not possible since they are supposed
> to be garbage collected.

A Lua function, even if implemented in C, has an environment and
upvalues. As such it's more than a C function pointer, and for that
reason, you cannot extract a C function pointer from a Lua function
implemented in C.

However, if you want to call that function, and you have it on the Lua
C API stack, you don't have to extract the function pointer and call
it. You can use the lua_call or lua_pcall functions to invoke that
function.

If you want to keep a reference to that function in C structures,
things are a little more complicated. It involves using
luaL_ref/luaL_unref, and storing the lua_State pointer along with the
reference int. Ask if you want to learn about that method.

>> You can use a Lua script such as the one you propose, but instead of
>> making the new functions accessible in a global variables, you can
>> pass them as parameters to the script. To pass them from C, push the
>> functions on the stack before calling the script, and pass appropriate
>> arguments to lua_call. From within the script, to access the
>> parameters passed when the script was called you have to use the three
>> dots "...". You would simply prefix the script with a line or two like
>> :
>>
>> local myown_index_method,myown_newindex_method = ...
>
> I wanted to try this workflow by simply pushing a number from C to a Lua
> script that calls the print function. That means, I should pass "print(...)"
> to luaL_loadstring and before I have to push the number. Well, it failed
> naturally.  Do you have some code snippets from which I learn how to use the
> interface?

Here is a simple C snippet creating a function implemented in Lua, and
invoking it with a single number parameter, and no result value:

if (luaL_loadstring(L, "print(...)"))
{
  fprintf(stderr, "loadstring error: %s\n", lua_tostring(L, -1));
  lua_pop(L, 1);
  return;
}
lua_pushnumber(L, 42);
if (lua_pcall(L, 1, 0, 0))
{
  fprintf(stderr, "pcall error: %s\n", lua_tostring(L, -1));
  lua_pop(L, 1);
  return;
}