In the book, working with this function is described like this:

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int creat (const char *name, mode_t mode) 

However, when running in lua code

 ffi = require 'ffi' ffi.cdef [[int creat (const char *name, mode_t mode)]] 

An error occurs:

 stdin:1: unknown type mode_t on line 1 stack traceback: [C]: in function 'cdef' stdin:1: in main chunk [C]: in ? 

Apparently, the problem arises from the fact that the type is not described with #include . How can this problem be solved?

UPD : following the advice to use lcpp came to this lcpp :

 > lcpp = require("lcpp") > ffi = require("ffi") > ffi.cdef[[ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int creat (const char *name, mode_t mode) ]] stack traceback: /home/v/.luarocks/share/lua/5.2/lcpp.lua:232: in function 'error' /home/v/.luarocks/share/lua/5.2/lcpp.lua:1382: in function 'compileFile' /home/v/.luarocks/share/lua/5.2/lcpp.lua:746: in function </home/v/.luarocks/share/lua/5.2/lcpp.lua:745> (...tail calls...) /home/v/.luarocks/share/lua/5.2/lcpp.lua:735: in function '_doWork' /home/v/.luarocks/share/lua/5.2/lcpp.lua:742: in function </home/v/.luarocks/share/lua/5.2/lcpp.lua:742> /home/v/.luarocks/share/lua/5.2/lcpp.lua:1367: /home/v/.luarocks/share/lua/5.2/lcpp.lua:232: lcpp ERR [0000] file not found: sys/types.h stack traceback: [C]: in function 'for iterator' /home/v/.luarocks/share/lua/5.2/lcpp.lua:1367: in function 'compile' /home/v/.luarocks/share/lua/5.2/lcpp.lua:1931: in function 'lcpp' /home/v/.luarocks/share/lua/5.2/lcpp.lua:1939: in function 'cdef' stdin:1: in main chunk [C]: in ? 
  • ffi.cdef [[int creat (const char *name, mode_t mode]] way, your bracket is not closed: ffi.cdef [[int creat (const char *name, mode_t mode]] - aleksandr barakin

2 answers 2

probably by analogy with this :

 ffi.cdef[[ typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef. int dofoo(foo_t *f, int n); /* Declare an external C function. */ ]] 

You need to add a typedef for mode_t . (another longer example found).


what exactly to substitute as type?

  1. In sys/types.h type mode_t defined as __mode_t :

     $ grep '\<mode_t' /usr/include/*/sys/types.h typedef __mode_t mode_t; 
  2. in bits/types.h type __mode_t defined as __MODE_T_TYPE :

     $ grep '__mode_t' /usr/include/*/bits/types.h __STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */ 
  3. in bits/typesizes.h type __MODE_T_TYPE defined as a “synonym” __U32_TYPE :

     $ grep __MODE_T_TYPE /usr/include/*/bits/typesizes.h #define __MODE_T_TYPE __U32_TYPE 
  4. in bits/types.h type __U32_TYPE defined as a “synonym” unsigned int :

     $ grep -r __U32_TYPE /usr/include/*/bits/types.h #define __U32_TYPE unsigned int 

i.e., apparently, you need to call ffi.cdef like this:

 ffi.cdef [[ typedef unsigned int mode_t; int creat (const char *name, mode_t mode); ]] 

update :

and here , for example, they suggest directly using #include (for mode_t this will be sys/types.h ):

 ffi.cdef("#include <your_header.h>") 

maybe that will work.

  • "Real sichniki" will certainly be able to suggest a more efficient method of searching for all these macros / definitions. - aleksandr barakin

For this purpose it would be appropriate to use this library . True, now it is not suitable for this purpose, since it does not know how to use paths from system sources. The version I corrected (open pull request ) here .

Now the connection looks like this:

 ffi.cdef[[ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int creat (const char *name, mode_t mode) ]]