lua-users home
lua-l archive

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


You could also maybe look at the example bitarray in the book
"Programming in Lua" by Roberto, this really is very instructively
showing how to some addon and later add metatables... .


On Wed, Oct 20, 2021 at 12:46 PM Jairo A. del Rio
<jairoadelrio6@gmail.com> wrote:
>
> Hi, list. I'm trying to understand how to write Lua modules from C (I use GSL as an example). Code is below.
>
> #include <gsl/gsl_vector.h>
> #include "lua.h"
> #include "lauxlib.h"
>
> #define VECTOR_MT "GSL vector"
>
> static int vector_new(lua_State *L)
> {
>   int i;
>   int n = lua_gettop(L);
>   gsl_vector *t = gsl_vector_alloc(n);
>   for (i = 0; i < n; i++)
>   {
>     gsl_vector_set(t, i, luaL_checknumber(L,i+1));
>   }
> //Is this right?
>   gsl_vector *r = (gsl_vector *)lua_newuserdata(L, sizeof(gsl_vector));
>   *r = *t;
>   luaL_getmetatable(L, VECTOR_MT);
>   lua_setmetatable(L, -2);
>   return 1;
> }
>
> static int vector_get(lua_State *L)
> {
>   gsl_vector *v = (gsl_vector *)lua_touserdata(L,1);
>   int max = (int)v->size;
>   int n = luaL_checkinteger(L,2)-1;
>   if ((0<=n) && (n <= max))
>     lua_pushnumber(L, gsl_vector_get(v,n));
>   else
>     lua_pushnil(L);
>   return 1;
> }
>
> static int vector_m_add(lua_State *L)
> {
>   gsl_vector *v1 = (gsl_vector *)lua_touserdata(L,1);
>   gsl_vector *v2 = (gsl_vector *)lua_touserdata(L,2);
>   if ((v1 -> size) == (v2 -> size))
>   {
> // I'm not sure whether this is right or not, but it seems to work so far
>     gsl_vector *t = gsl_vector_alloc(v1 -> size);
>     gsl_vector_memcpy(t, v1);
>     gsl_vector_add(t,v2);
>     gsl_vector *r = (gsl_vector *)lua_newuserdata(L, sizeof(gsl_vector));
>     luaL_getmetatable(L, VECTOR_MT);
>     lua_setmetatable(L, -2);
>     *r = *t;
>   }
>   else
>   {
>     lua_pushnil(L);
>   }
>   return 1;
> }
>
> static const struct luaL_Reg nicelib [] =
> {
>   {"new", vector_new},
>   {"get", vector_get},
> {NULL, NULL}
> };
>
> static const struct luaL_Reg nicelib_m [] =
> {
>   {"__add", vector_m_add},
>   {NULL, NULL}
> };
>
> int luaopen_nice(lua_State *L)
> {
>   luaL_newmetatable(L, VECTOR_MT);
>   lua_pushvalue(L, -1);
>   lua_setfield(L, -2, "__index");
>   luaL_setfuncs(L, nicelib_m, 0);
>   luaL_newlib(L, nicelib);
>   return 1;
> }
>
> I have two questions:
>
> 1. Am I right wrt "new", i.e., the way userdata is created?
> 2. According to some docs I've read, userdata content should be freed by defining a function for __gc. However, I don't understand when or how to do that, as defining a function using gsl_vector_free in the case above is giving me an error prompt complaining about an invalid pointer.
>
> I don't want a ready-made application to create bindings to GSL or an already existing one (I think two are freely available in GitHub) as I only use it as an example. I don't want a Lua solution, either (I know how to do that using pure Lua). Instead, I want to better understand the way Lua modules are defined when C is used, and perhaps to better understand C given that pointers are not intuitive for me. Thank you in advance and sorry for any inconvenience caused by this noob question.
>
> Best regards,
>
> Jairo