我必须为以下函数Abc_NtkCreateNodeAnd
制作一个ruby 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;
}
以下是ruby 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。我试图像这样编写扩展名:
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);
在我看来是错误的。那么什么应该是正确的代码?
答案 0 :(得分:1)
很大程度上取决于Abc_Obj_t
是什么类型的事物,以及您希望如何管理它的内存分配。我猜它是一个C结构,并且当它返回一个指向它的指针作为Ruby VALUE时,你会想要在内存超出作为Ruby变量的范围时管理释放内存。
Abc_Ntk_t *netw_str = StringValueCStr(netw);
的问题是StringValueCStr
返回指向char
的指针,所以它不会编译(看起来你希望C或Ruby的库可以添加一些类型强制,但他们不会 - 在C中可用的类型转换比这更基本)。你在第一个例子中做得更好。您的一般方法应该是:首先将VALUE中的输入转换为匹配的C类型(即String to char *,Fixnum to int),然后在C中处理以获取所需的库对象。然后将返回的数据包装为Ruby VALUE。
我建议您先在这个非常有用的指南中查看Data_Wrap_Struct
及相关文档:http://media.pragprog.com/titles/ruby3/ext_ruby.pdf - 2.4 部分可能是检查相关示例的好地方。该指南曾经是镐书的一部分,但作者慷慨地公开发布了它。