[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Newby question: How to change __index userdata method in C?
- From: Sebastian Wolff <sw@...>
- Date: Thu, 3 Dec 2009 17:33:16 +0100
I am sorry for letting you know my frustration and my last "moody" and
aggressive reply. Maybe it is better to clarify what my problem is:
I want to exchange the existing __index and __newindex metamethods by
some C functions. This could be done like this:
static lua_CFunction TMMatrix_original_index;
static lua_CFunction TMMatrix_original_newindex;
int TMMatrix_redefined_index(lua_State *L)
{
printf("CALLED redefined __index!\n");
return (*TMMatrix_original_index)(L);
}
int TMMatrix_redefined_newindex(lua_State *L)
{
printf("CALLED redefined __newindex!\n");
return (*TMMatrix_original_newindex)(L);
}
I then register these functions. SWIG created a module "tm" which is
represented as a table in Lua:
const luaL_reg lua_mymatrix_functions[] =
{
{"TMMatrix_redefined_index", TMMatrix_redefined_index},
{"TMMatrix_redefined_newindex", TMMatrix_redefined_newindex},
{NULL,NULL},
};
luaL_register(L, "tm", lua_mymatrix_functions);
Then I call the following Lua script using luaL_dostring:
local metaarray = getmetatable(tm.TMMatrix(1,1))
__oldindex = metaarray.__index
__oldnewindex = metaarray.__newindex
metaarray.__index = tm.TMMatrix_redefined_index
metaarray.__newindex = tm.TMMatrix_redefined_newindex
which creates a variable of userdata type tm.TMMatrix and changes its
metatable.
I have stored the old metamethods in global variables. Thanks to your
advice, Jerome, I can now save them in global C variables:
lua_getglobal(L, "__oldindex");
TMMatrix_original_index = lua_tocfunction (L, -1);
lua_pop(L,1);
lua_getglobal(L, "__oldnewindex");
TMMatrix_original_newindex = lua_tocfunction (L, -1);
lua_pop(L,1);
Executing the Lua script
A = tm.TMMatrix(2,2)\n"
y = A[1]
A:func1(2)
A[0] = 2
Will now call my own C functions and they in turn will call the
original wrapper C functions.
So far so good. It is working, but the code is the opposite of being
elegant. (1) I would like to eliminate the need of the global Lua
variables __index and __oldindex.
(2) I would like to eliminate the script itself.
(3) I would like to eliminate the need of registering my 2 new functions.
For (1) and (2) I think what could help me is to know how I can get the
metatable of a locally created object. Unfortunately I do not know how
to create the userdata value "TMMatrix(3,3)" from C since that code is
behind some blackbox wrapper, i.e. performing the Lua code
local metaarray = getmetatable(tm.TMMatrix(1,1))
on C level. Once I have the metatable on stack I should be able to
retrieve the metatable field "__index" (at least I hope so).
For (3) it would be nice to be able to perform the Lua code
metaarray.__index = tm.TMMatrix_redefined_index
in such a way that I do not need to register the function
"tm.TMMatrix_redefined_index". You said this is possible (I would agree
with that), but I didn't figure out, how - Maybe, if I can solve (1)
and (2), then I can simply change the function pointer on C level which
is stored on the Lua stack?
Thanks Sebastian