I tried to call function tan
of math.h
this way (directly copy the declaration) and it works:
local ffi = require("ffi")
ffi.cdef[[
double tan(double x);
]]
print(ffi.C.tan(45))
But when I tried to call the function localtime
of time.h
the same way:
local ffi = require("ffi")
ffi.cdef[[
struct tm *localtime(const time_t *tp);
]]
print(ffi.C.localtime(1234544))
And get error:
lua: C:\Users\xiang\Desktop\bm.lua:4: declaration specifier expected near 'time_t'
stack traceback:
[C]: in function 'cdef'
C:\Users\xiang\Desktop\bm.lua:4: in main chunk
[C]: at 0x00401f00
[Finished in 0.1s with exit code 1]
I've checked the official manual this and this but still confused.
Every function you would like to call from FFI, it needs to be defined before. If not LuaJIT does not how to parse a FFI function call, how to do data-type conversion from Lua to C (and viceversa), etc.
Keeping that in my mind, to make your code work you would need to define time_t
and struct tm
. time_t
is generally defined as a signed integer. You can find the definition of struct tm
in localtime docs (man localtime).
ffi.cdef[[
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
struct tm *localtime(const int32_t *tp);
]]
In addition, function localtime
expects a pointer value, not a constant integer. So it would be necessary to pass a c-data pointer storing an integer to localtime
. There's a sort of LuaJIT idiom for that.
local time = ffi.new("int32_t[1]")
time[0] = 1234544
local tm = C.localtime(time)
Since arrays and pointers in C, although not the exactly same, are interchangeable in most cases.
Lastly, you cannot print a struct tm
directly. Should store it into a variable and print out the fields you're interested.
print(tm.tm_sec)