【问题标题】:Luajit ffi how to call funcitons in time.h?Luajit ffi如何在time.h中调用函数?
【发布时间】:2016-09-24 09:52:36
【问题描述】:

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

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

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

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,但仍然感到困惑。

【问题讨论】:

    标签: lua ffi luajit


    【解决方案1】:

    您想从 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-data 指针传递给localtime。有一种 LuaJIT 习惯用法。

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

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

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

    print(tm.tm_sec)
    

    【讨论】:

      【解决方案2】:

      您不能使用time_t,因为它不是本机 C 类型。将其替换为适当的本机类型或使用相应的结构 typedef。那么它应该可以工作了。

      【讨论】:

        猜你喜欢
        • 2012-09-01
        • 2014-08-08
        • 1970-01-01
        • 2014-12-28
        • 2019-09-21
        • 1970-01-01
        • 2016-08-11
        • 1970-01-01
        • 2017-06-03
        相关资源
        最近更新 更多