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 に答える