首页 文章

luajit ffi实现了一个块终结器

提问于
浏览 713
1

我正在研究在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

BTW CURL定义为 typedef void CURL; I 'm sure the way I am trying to do it isn' t足够干净 . 任何建议?

eureka ! : self answer -- still interested in comments if there any glaring issues.

2 回答

  • 3

    如果将上下文类型初始化为指针,则luajit中的编译时间类型必须为 structs (或 unions 我认为),它不再是 struct . 因此,这里存在概念不匹配 . 因此,要修复问题,请在 struct 中添加 void * ,在 struct 上挂起 metatype ,并使用 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();
    
  • 1

    或者您可以在返回的指针上注册终结器,如下所示:

    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() -- wrapper func
    print "done"
    

相关问题