Luajit ffi 实现一个块终结器。

我正在使用luajit ffi将libcurl包装起来。我的终结器没有被调用。

local ffi = require("ffi")

ffi.cdef [[
  typedef struct{} CURL;
  CURL * curl_easy_init();
  void curl_easy_cleanup(CURL *);
]]

local CURL_lib = ffi.load("../lib/libcurl.so")
local CURL_CTX

local CURL_CTX_mt = {
  __gc = function()  print "finalizing"; CURL_lib.curl_easy_cleanup(CURL_CTX); end
}

ffi.metatype("CURL", CURL_CTX_mt)

CURL_CTX = ffi.new("CURL[1]")
CURL_CTX = CURL_lib.curl_easy_init();
print "done"

我错过了什么? :D

顺便说一下,CURL被定义为typedef void CURL;我确定我尝试的方式还不够完美。有什么建议吗?

有了启示!:自我答案-- 如有任何明显的问题,请仍然欢迎评论。

原文链接 https://stackoverflow.com/questions/9395985

点赞
stackoverflow用户153865
stackoverflow用户153865

在 luajit 中,编译时类型必须是 structs(或者 unions,我想),如果你将上下文类型初始化为指针,则不再是 struct。因此,在这里存在概念不匹配的问题。所以,为了修复问题,在你的 struct 中添加一个 void *,将 metatype 挂载到 struct 上,并使用 void * 作为库上下文。

local ffi = require("ffi")

ffi.cdef [[
  typedef struct { void * ctx; } curl;
  curl * curl_easy_init();
  void curl_easy_cleanup(curl *);
]]

local curl_lib = ffi.load("../lib/libcurl.so")
local curl

local curl_mt = {
  __gc = function()  curl_lib.curl_easy_cleanup(curl.ctx); end
}

local curl_proto = ffi.metatype("curl", curl_mt)

curl = curl_proto(nil)
curl.ctx = curl_lib.curl_easy_init();
2012-02-22 14:13:29
stackoverflow用户70405
stackoverflow用户70405

或者您可以像这样在返回的指针上注册终结器:

local ffi = require("ffi")

ffi.cdef [[
    typedef struct{} CURL;
    CURL * curl_easy_init();
    void curl_easy_cleanup(CURL *);
]]

local CURL_lib = ffi.load("../lib/libcurl.so")

local function curl_pointer_finalizer(pointer)
    print "finalizing"
    CURL_lib.curl_easy_cleanup(pointer)
end

local function curl_easy_init()
    return ffi.gc(CURL_lib.curl_easy_init(), curl_pointer_finalizer)
end

local CURL_CTX = curl_easy_init() -- 包装器函数
print "done"
2014-01-28 23:21:20