From: Chris Uzdavinis Date: 2001-07-17T03:54:26+09:00 Subject: [ruby-talk:17943] Re: RUBY C++ Extension Sean Middleditch writes: > On Tue, Jul 17, 2001 at 01:54:18AM +0900, Bernhard Gl?ck wrote: > > Does anybody have the source to a WORKING C++ Class exported to > > RUBY (preferably using MSVC 6.0) ? I would like to instantiate my > > C++ classes in RUBY just the way as in C++ code. All samples and > > docs I found are on straigt C Extensions and that does not help > > much. > > I dunno how other people do it, but I wrap the C++ calls in C > functions. Pass the C++ class pointer along with the Ruby object, > cast it in the C function, and have it call the proper C++ method. That's probably the best way to do it. I'm finding that writing ruby extension functions in C++ is very problematic, since when a ruby function throws an exception, all auto (stack based) objects in the C++ extenstion function are not cleaned up due to the longjmp. This situation is specifically described in the C++ standard as having undefined behavior. There are really only a few solutions, none are very satisfying: 1) don't create any C++ stack based objects in a C++ extension function, unless they do not have destructors needing to be invoked. (Structures containing only data of builtin-types is the only ok type of local data.) 2) create a struct on the heap, and wrap that struct in a Ruby object that gets registered with teh garbage collector. The data in that struct can serve as your "local" variables. But you have less deterministic object lifetimes (since they get destroyed when the GC kicks in, not when they go "out of scope.") 3) Change the internals of Ruby to not use setjmp/longjmp for its exception handling, but to instead return some error code. There is a preprocessor macro solution which can "simulate" exceptions like this, as is done by the ACE C++ framework (which implements exceptions very similar to C++ exceptions for compilers which do not have native C++ exceptions.) This technique will work in C as well, I think. Of course, this chagnes just about everything in Ruby, and would break everything, and be a massive job. But maybe it's a good idea for a future version. (Not very practical right now, but it's worth thinking about.) -- Chris