From: Tony Smith Date: 2002-01-11T19:54:56+09:00 Subject: Re: Extension with C++ On Friday 11 January 2002 05:03, Mahina wrote: > I'm a beginner in programming Ruby. > I want to use it for my works. > But i have a problem. I didn't understand, how extend Ruby with C++. > Though i already read chapter "Extending Ruby" in Programming Ruby. > What can you advice me? Marrying Ruby and C++ can be a little awkward as Dave and Andy mention in the book. The trick is to write most of your glue code in C++, but with C bindings i.e. not object oriented. That way, Ruby calls a regular "C" function, which can then invoke C++ methods on C++ objects ( or indeed Ruby methods on Ruby objects ) Check out: http://public.perforce.com:8080/guest/tony_smith/perforce/API/Ruby/main/ for my implementation of a Ruby extension to a C++ api. I'm sure there are other (and probably better) examples at the RAA too. A short snippet which illustrates the point. Taken from p4.cc: extern "C" { static VALUE p4_new( VALUE pClass ) { VALUE argv[ 1 ]; P4ClientApi *p4 = new P4ClientApi(); VALUE self; self = Data_Wrap_Struct( pClass, p4_mark, p4_free, p4 ); rb_obj_call_init( self, 0, argv ); return self; } static VALUE p4_set_client( VALUE self, VALUE client ) { P4ClientApi *p4; Data_Get_Struct( self, P4ClientApi, p4 ); p4->SetClient( STR2CSTR( client ) ); return Qtrue; } void Init_P4api() { // Ruby instantiation eP4 = rb_define_class( "P4Exception", rb_eRuntimeError ); cP4 = rb_define_class( "P4", rb_cObject ); rb_define_singleton_method( cP4, "new", (VALUE (*)() ) p4_new, 0 ); rb_define_method( cP4, "initialize", (VALUE (*)() )p4_init, 0 ); rb_define_method( cP4, "client", (VALUE (*)() )p4_set_client, 1 ); // Lots more method definitions... } } // Extern C You can see that the C++ object is created in p4_new() and wrapped in a Ruby object of the given class. The "C" functions (actually C++ but with unmangled names) then use Data_Get_Struct() to extract the C++ object from the Ruby object and call the appropriate method. Hope that helps! Tony