Nuron
Nuron

Reputation: 109

Ruby C extension for a function

I have to make a ruby c extension for the following function 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;
}

Here is an example of the ruby c extension.

*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);
}

Now my main problem is how do you pass the pointer from c to ruby.I have tried to write the extension like this :

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);
 }

but the code Abc_Ntk_t *netw_str = StringValueCStr(netw); is wrong in my opinion.So what should be the proper code ?

Upvotes: 3

Views: 215

Answers (1)

Neil Slater
Neil Slater

Reputation: 27207

It depends a lot on what type of thing a Abc_Obj_t is, and how you expect to manage the memory allocations for it. I'm guessing it's a C struct, and as well as returning a pointer to it back as a Ruby VALUE, you will want to manage freeing up memory when it goes out of scope as a Ruby variable.

The problem with Abc_Ntk_t *netw_str = StringValueCStr(netw); is that StringValueCStr returns a pointer to char, so it won't compile (looks like you were hoping that C or Ruby's libraries could add some type coercion, but they will not - type conversions available to you in C are more basic than that). You had this better in your first example. Your general approach should be: First convert inputs in VALUEs into matching C types (i.e. String to char *, Fixnum to int), then process in C to get your desired library object. Then wrap the returned data up as a Ruby VALUE.

I suggest you first take a look at Data_Wrap_Struct and related documentation in this very useful guide: http://media.pragprog.com/titles/ruby3/ext_ruby.pdf - section 2.4 may be a good place to check for relevant examples. The guide used to be part of the pickaxe book, but the author has generously posted it publicly for free.

Upvotes: 1

Related Questions