Luajit ffi如何在time.h中调用函数?

时间:2016-09-24 09:52:37

标签: lua ffi luajit

我尝试以这种方式调用tan的函数math.h(直接复制声明)并且它有效:

local ffi = require("ffi")
ffi.cdef[[
    double tan(double x);
]]
print(ffi.C.tan(45))

但是当我尝试以同样的方式调用localtime的函数time.h时:

local ffi = require("ffi")
ffi.cdef[[
    struct tm *localtime(const time_t *tp);
]]
print(ffi.C.localtime(1234544))

得到错误:

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]

我查看了官方手册thisthis,但仍然感到困惑。

2 个答案:

答案 0 :(得分:2)

您想从FFI调用的每个函数,都需要先定义。如果不是LuaJIT不怎么解析FFI函数调用,那么如何从Lua到C(反之亦然)等进行数据类型转换。

在我看来,要使代码正常工作,您需要定义time_tstruct tmtime_t通常定义为有符号整数。您可以在localtime docs( man localtime )中找到struct tm的定义。

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);
]]

此外,函数localtime需要指针值,而不是常量整数。因此,有必要将存储整数的c数据指针传递给localtime。对此有一种LuaJIT习语。

local time = ffi.new("int32_t[1]")
time[0] = 1234544
local tm = C.localtime(time)

由于C中的数组和指针虽然不完全相同,但在大多数情况下都是可以互换的。

最后,您无法直接打印struct tm。应将其存储到变量中并打印出您感兴趣的字段。

print(tm.tm_sec)

答案 1 :(得分:0)

您不能使用time_t,因为它不是本机C类型。用适当的本机类型替换它或使用相应的struct typedef。然后它应该工作。