From: Phlip Date: 2006-10-02T01:25:15+09:00 Subject: Re: I'm trying to integrate my C++ program with Ruby using SWIG in WinXP bryanedds wrote: > All I can find is some outdated docs with command line instructions > that don't work. Can someone please point in differenct direction? Raw Ruby is easier than SWIG - even when you need all of SWIG's features. Here's some of my integrational code. First, we have a super-thin wrapper for the Ruby VALUE type, the root type of all Ruby expressions: class rbValue { public: rbValue(VALUE nuV = Qnil): v(nuV) {} rbValue(char const * gv): v(Qnil) { assert(gv); assert('$' == gv[0]); // documentation sez this is optional. We don't agree v = rb_gv_get(gv); } operator VALUE() const { return v; } // TODO deprecate me rbValue &operator =(VALUE nuV) { v = nuV; return *this; } // TODO deprecate me rbValue fetch(char const * tag) { return funcall("fetch", 2, rb_str_new2(tag), Qnil); } rbValue fetch(int idx) { return funcall("fetch", 2, INT2FIX(idx), Qnil); } rbValue fetch(size_t idx) { return funcall("fetch", 2, INT2FIX(idx), Qnil); } VALUE * getPtr() { assert(T_ARRAY == TYPE(v)); return RARRAY(v)->ptr; } long getLen() { assert(T_ARRAY == TYPE(v)); return RARRAY(v)->len; } rbValue getAt(long idx) { assert(idx < getLen()); return RARRAY(v)->ptr[idx]; } rbValue operator[](long idx) { return getAt(idx); } bool isNil() { return Qnil == v; } double to_f() { assert(T_FLOAT == TYPE(v) || T_FIXNUM == TYPE(v)); return NUM2DBL(v); } char const * to_s() { assert(T_STRING == TYPE(v)); return STR2CSTR(v); } rbValue funcall ( char const * method, int argc = 0, VALUE arg1 = Qnil, VALUE arg2 = Qnil, VALUE arg3 = Qnil ) { return rb_funcall(v, rb_intern(method), argc, arg1, arg2, arg3); } rbValue iv_get(char const * member) { VALUE iv = rb_iv_get(v, member); return iv; } void iv_set(char const * member, VALUE datum) { rb_iv_set(v, member, datum); } void iv_set(char const * member, int datum) { iv_set(member, INT2FIX(datum)); } private: VALUE v; }; // a smart wrapper for the Ruby VALUE type You simply use it the way you think to use a Ruby value, and (like Ruby) it will defend the actual wrapped type at runtime. Unlike Ruby, it will defend by breaking an assertion. You might like to throw, or you might write strongly-typed code and never break. Read the Ruby documentation for extending to C. Extend to C-style C++, and call a Ruby script. If it creates a global variable called $egg, you can retrieve this variable and use it in C++ like this: egg = rbValue("$egg"); if (egg.isNil()) return false; out = rbValue("$out"); assert(!out.isNil()); ax = egg.iv_get("@rootAxioms").funcall("first"); assert(!ax .isNil()); And so on. The result looks like Ruby, but with extra iv_get() and funcall() between everything. From here, writing new C++ to drive Ruby is very easy, and converting Ruby to Ruby-style C++ is also super easy. -- Phlip http://www.greencheese.us/ZeekLand <-- NOT a blog!!!