Reputation: 2544
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.
Upvotes: 1
Views: 1713
Reputation: 11586
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)
Upvotes: 3
Reputation: 1
You cannot use time_t
as it isn't native C type. Replace it with proper native type or use a corresponding struct typedef. Then it should work.
Upvotes: 0