3

我必须为以下功能制作一个 ruby​​ c 扩展Abc_NtkCreateNodeAnd

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);我认为代码是错误的。那么正确的代码应该是什么?

4

1 回答 1

1

这在很大程度上取决于 a 是什么类型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节可能是检查相关示例的好地方。该指南曾经是镐书的一部分,但作者慷慨地免费公开发布。

于 2013-06-24T08:43:52.010 回答