[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: setmetatable from C code
- From: Sean Conner <sean@...>
- Date: Mon, 27 Jun 2011 16:35:24 -0400
It was thus said that the Great Björn Eiríksson once stated:
> Hello
>
> I have made a test class in C code that exposes it self to Lua, it mostly
> works, the only problem is that I cannot get the setmetatable code to work
> from C++, so for testing purposes I have been setting that on the Lua side
> to verify that everything else works indeed.
>
> Lua test code is as follows:
>
> vec = CustomVector:new(1, 2, 3) -- CustomVector is defined in C code
>
> setmetatable(vec, { __index = CustomVector }) -- This one should be done
> in C code but I could not get it to work if I have it there.
>
> io.write("<"..vec.x.." , "..vec.y.." , "..vec.z..">\n")
>
> io.write(vec:Magnitude().."\n")
>
> So my question is, does anyone have a example of how to do the
> setmetatable for case like this from C code ?
What I do is the following (from some code I have):
static const struct luaL_Reg hashlua[] =
{
{ "new" , hashlua_new } ,
/* ... */
{ NULL , NULL }
};
static const struct luaL_Reg hashlua_meta[] =
{
{ "update" , hashlua_update } ,
{ "final" , hashlua_final } ,
{ "finalhexa" , hashlua_finalhexa } ,
{ "__tostring" , hashlua___tostring } ,
{ NULL , NULL }
};
int luaopen_org_conman_hash(lua_State *const L)
{
OpenSSL_add_all_digests();
luaL_newmetatable(L,HASH_TYPE);
luaL_register(L,NULL,hashlua_meta);
lua_pushvalue(L,-1);
lua_setfield(L,-2,"__index");
luaL_register(L,"org.conman.hash",hashlua);
/* rest of function */
}
This creates a metatable I can use with the "__index" field pointed to
itself. In the code to create a new instance, I grab the metatable I
created:
static int hashlua_new(lua_State *const L)
{
const EVP_MD *m;
EVP_MD_CTX *ctx;
const char *alg;
alg = luaL_optstring(L,1,"md5");
m = EVP_get_digestbyname(alg);
if (m == NULL)
{
lua_pushnil(L);
return 1;
}
ctx = lua_newuserdata(L,sizeof(EVP_MD_CTX));
EVP_DigestInit(ctx,m);
luaL_getmetatable(L,HASH_TYPE);
lua_setmetatable(L,-2);
return 1;
}
I use separate tables for main objects and metatables (I personally find
it cleaner that way) but there's no technical reason you can't use the same
table for both.
-spc (I do hope this helps)