2012-02-22 27 views
1

我正在努力在luajit ffi中包裝libcurl。我的終結者沒有被調用。luajit ffi實現塊終結器

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;我確信我嘗試做的方式不夠乾淨。有什麼建議?

eureka! :自我回答 - 如果有任何明顯的問題,仍然對評論感興趣。在luajit

+0

如果你發現自己的答案,你應該張貼它作爲一個實際的答案,並接受它。 – Necrolis 2012-02-22 14:11:43

+0

aah我以爲在自我回答完成之前,我必須等待超時。謝謝。啊,你不能接受你自己的答案2天。 – 2012-02-22 14:13:00

回答

3

編譯時類型必須structs(或unions我認爲)如果你初始化上下文類型的指針,它不再是一個struct。所以,這裏有一個概念不匹配。因此,要解決問題,請將void *添加到您的struct,將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(); 
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"