2013-06-24 44 views
3

我必須作出以下功能Abc_NtkCreateNodeAnd紅寶石C擴展:紅寶石C擴展爲一個函數

Abc_Obj_t * Abc_NtkCreateNodeAnd(Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins) 
{ 
Abc_Obj_t * pNode; 
int i; 
pNode = Abc_NtkCreateNode(pNtk); 

return pNode; 
} 

這裏是紅寶石C擴展的一個例子。現在

*Original C function* 

Abc_Ntk_t * Io_ReadBlif(char * pFileName, int fCheck) 
{ 
Io_ReadBlif_t * p; 
Abc_Ntk_t * pNtk; 
p = Io_ReadBlifFile(pFileName); 
return pNtk; 
} 


*Ruby C extension* 

static VALUE IO_read_blif(VALUE self, VALUE file_name) 
{ 
int index; 
char *file_name_str = StringValueCStr(file_name); 
Abc_Ntk_t *network = Io_ReadBlif(file_name_str, IO_FILE_BLIF, 1); 
} 

我的主要問題是你如何從C到ruby.I傳遞指針已經嘗試寫擴展這樣的:

static VALUE Abc_NtkCreateNode_And(VALUE self, VALUE netw ,VALUE vfan_ins) 
{ 
    Abc_Ntk_t *netw_str = StringValueCStr(netw); 
    Vec_Ptr_t *vfan_ins_str = StringValueCStr(vfan_ins); 
    Abc_Obj_t *network = Abc_NtkCreateNodeAnd(netw_str,vfan_ins_str, IO_FILE_BLIF, 1); 
    return make_Network(network); 
} 

但代碼Abc_Ntk_t *netw_str = StringValueCStr(netw);是錯誤的,我的意見。那麼適當的代碼應該是什麼?

回答

1

這很大程度上取決於Abc_Obj_t是什麼類型的東西,以及您希望如何管理內存分配。我猜它是一個C結構體,並且將一個指針返回爲Ruby VALUE,當它作爲Ruby變量超出範圍時,您將需要管理釋放內存。

Abc_Ntk_t *netw_str = StringValueCStr(netw);的問題是,StringValueCStr返回一個指針char,所以它不會編譯(看起來像你所希望看到的是C或Ruby的庫可以添加一些類型轉換,但他們不會 - 類型轉換提供給您在C中比這更基礎)。你的第一個例子中你有這個更好。您的一般方法應該是:首先將VALUE中的輸入轉換爲匹配的C類型(即String到char *,Fixnum到int),然後在C中處理以獲取所需的庫對象。然後將返回的數據作爲Ruby VALUE包裝起來。

我建議你先看看Data_Wrap_Struct和相關文檔這個非常有用的指南:http://media.pragprog.com/titles/ruby3/ext_ruby.pdf - 部分2.4可能是檢查相關的例子的好地方。該指南曾經是鎬書的一部分,但作者慷慨地公開免費發佈。