Search code examples
ffiluajit

why LuaJIT typeof template failed


I don't understand why the following code snipped is invalid. Could anyone explain it? Thanks. (I think my code is same as gilbo's(How can I create a pointer to existing data using the LuaJIT FFI?))

  local ffi = require("ffi")

  ffi.cdef[[
  typedef struct my_s {
      int a;
      int b;
      char c[24];
  } my_t;

  typedef void (*finalizer)(void *ptr);

  bool my_is_equal(const my_t *m1, const my_t *m2);
  const char *my_to_str(const my_t *m);
  my_t *new_my(int a, int b, const char *c);
  my_t *my_copy(const my_t *m);
  void free_my(my_t *m);
  ]]

  local obj_wrapper = function (type_str)
      return ffi.typeof("struct { $ *val; finalizer fnlz; }", type_str)
  end

  local my_ltype = obj_wrapper("my_t")
  --local my_ltype = ffi.typeof("struct { my_t *val; finalizer fnlz; }")
  ffi.metatype(my_ltype, {
      __tostring = function (self)
          print("enter lua function: __tostring")
          local buf = ffi.cast("char *", ffi.C.my_to_str(self.val))
          return ffi.string(buf)
      end,
  })

and load error is:

dofile(test.lua) failed:test.lua:23: declaration specifier expected near '$'

My OS is macOS 12.2.1 and LuaJIT 2.1.0-beta3

Could anyone explain the LuaJIT load error for me?


Solution

  • In gilbo's code typestr is not a string, despite the parameter's name.
    It must be a ctype object returned by ffi.typeof:

    local ffi = require"ffi"
    ffi.cdef"typedef struct my_s { int a; int b; char c[24]; } my_t"
    local typestr = ffi.typeof("my_t")
    local ptr_typestr = ffi.typeof("struct { $ *val; int fnlz; }", typestr)
    

    See LuaJIT manual about replacing $ placeholders:

    A passed ctype or cdata object is treated like the underlying type, a passed string is considered an identifier and a number is considered a number.