Reputation: 109
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
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