Hi,

At Fri, 14 May 2004 16:43:54 +0900,
Jeff Mitchell wrote in [ruby-talk:100255]:
> This solution is nonportable -- perhaps someone can suggest a better
> way?  To be consistent, ruby could detect the presence/absence of a
> C++ compiler during ./configure, setting CONFIG['CXX'] and
> CONFIG['CXX_LDSHARED'].  Also, mkmf should know to use CXX_LDSHARED
> when C++ sources exist.

Indeed.  I'll consider about it.

> The easiest and saftest technique I found is to write three C
> functions for a ruby method: the actual ruby hook, the body, and the
> ensure:

You can use rb_protect() instead, and should use a struct
rather than ugly enumerated reinterpret_casts I guess.


#include "ruby.h" class CXXRuby { }; struct superfunk_args { int argc; VALUE *argv; VALUE self; CXXRuby cxx_obj; }; static VALUE rb_cxxruby_superfunk_body(VALUE); static VALUE rb_cxxruby_superfunk(int argc, VALUE * argv, VALUE self) { int status = 0; VALUE result; try { struct superfunk_args args = {argc, argv, self}; result = rb_protect(rb_cxxruby_superfunk_body, reinterpret_cast<VALUE>(&args), &status); } catch(...) { rb_raise(rb_eRuntimeError, "caught exception from an unfunky constructor"); } if (status) rb_jump_tag(status); return result; } static VALUE rb_cxxruby_superfunk_body(VALUE args) { struct superfunk_args *const argp = reinterpret_cast<struct superfunk_args *>(args); int argc = argp->argc; VALUE *argv = argp->argv; VALUE self = argp->self; CXXRuby &cxx_obj = argp->cxx_obj; VALUE get_out; VALUE the_funk; if (rb_scan_args(argc, argv, "11", &get_out, &the_funk) == 1) { the_funk = Qtrue; } // ... return self; } static VALUE cCXXRuby; extern "C" void Init_cxxruby(void) { cCXXRuby = rb_define_class("CXXRuby", rb_cObject); rb_define_singleton_method(cCXXRuby, "superfunk", RUBY_METHOD_FUNC(rb_cxxruby_superfunk), -1); rb_define_global_const("OperationSupergroove", cCXXRuby); }
-- Nobu Nakada