[wxruby-users] embedding wxruby?
Alex Fenton
alex at pressure.to
Mon Sep 15 06:50:27 EDT 2008
Hi Niklas
Niklas Baumstark wrote:
> as announced, I played a bit around with swig and now seem to have found a first solution for my embedded ruby GUI plugin system. So far, I managed to wrap a C++ wxWindow object into a ruby Wx::Window object.
>
Broadly, I think you should be able to use almost all of the existing
wxRuby SWIG etc codebase in an embedded setting. The main things that
will need to change are the library initialisation code (in swig/wx.i)
and the Wx::App initialisation code (in swig/classes/App.i) .
You will in some way need to link the wx C++ App object to a ruby
instance and make it a constant (like Wx::THE_APP in wxRuby). Having the
App as a constant is the link that wxRuby uses to protect long-lived C++
objects like Windows from Ruby's garbage collection (see mark_wxApp).
> ===== SAMPLE START =====
....
> * it is limited to be used with a wxWindow / Wx::Window and not at all generic.
>
Take a look at the function wxRuby_WrapWxObjectInRuby in swig/wx.i -
this does exactly what you want. It uses wxWidgets type-information
system to wrap a C++ object in the correct ruby class.
It is applied to (almost) all methods in wxWidgets that return wxWindow*
by a typemap.
> * the ruby script doesn't know about wxRuby. It just gets the raw
> Wx::Window object. it can't use $window.name instead of
> $window.get_name, for instance, and it can't access it's non-trivial
> members, because the corresponding types are not initialized.
> i didn't figure out a way to setup the whole wxRuby namespace in one rush
> (i would have to call every single Init_XY).
SWIG's support for multi-module libraries is weak so wxRuby has to work
around this by massaging the default generated code.
The rake build system (in rake/rakewx.rb) appends a function called
InitializeOtherModules to the generated file src/wx.cpp that initialises
all the other modules, in alphabetic order. This is then called in
Init_wxruby (in swig/wx.i).
The other important thing is that each class should not be initialised
before its parent class. The script swig/fixmodule.rb adds a line to
each generated cpp file that calls Init_wx[PARENTCLASS] before
proceeding with initialising self.
> the wx.rb could probably be included via rb_eval_string or something
> similiar for the sugar functionalities. didn't try it yet, however.
>
The ruby API function you want is rb_require. Some of the things in the
ruby code are not just "sugar" but needed to make the classes work
properly - eg GC helpers.
> * less important: the wxruby2.so has a size of 40MB. is it statically
> linked against wxWidgets? If so, can this easily be turned off?
You could try strip -x to reduce the size. But SWIG adds a lot of
overhead - the same runtime code is repeated and compiled for each SWIG
class. I estimate that just getting round that would reduce the library
size by about a third.
On Linux and OS X at least - haven't tried with Windows - you can have a
wxRuby that is dynamically linked. If you have a dynamic build
available, either have wx-config point to it by default, or pass
WXRUBY_DYNAMIC=1 as an environment variable to rake.
Happy to help further but may be better to follow-up on the wxruby-dev
list as this is fairly technical....
cheers
alex
More information about the wxruby-users
mailing list