gga,

gga wrote:
 > GD ha escrito:
 >
 >>I'm keeping things fairly simple; I mostly just bind functions/methods
 >>and wrap pointers in opaque data structures (eg. using Data_Wrap_Struct
 >>in the Ruby version). My plan was to store a pointer to the calling class
 >>in an opaque structure and store it in the corresponding Ruby class, so
 >>I can reference it when needed.
 >
 >
 > That's possible, but it can get ugly.  Do what SWIG does.  Create a
 > hash that stores a mapping between the ruby object and the C++ object
 > (and/or viceversa).  Every time you allocate a new class, you enter it
 > in the hash.  Every time the free function for the class is called, the
 > mapping is removed from the hash.
 > You can even use ruby's own hashes to do so.
 > That way, you don't need to pass any pointer, and can access any class
 > at any time from any function.
 > Also, if your classes contain or return pointers to other C++ classes,
 > you need to keep telling the GC about it.  See the SWIG Zoo/Animal
 > tutorial in the Ruby section.

This is an interesting idea but may be overkill for what I'm trying
to do.

 >> >>- The documentation is not at all clear how you protect something from the
 >> >>garbage collector, or indicate it is no longer in use.
 >> >
 >>
 >>Should some of the tricks used by SWIG be mentioned on the official
 >>Ruby site, perhaps? Seems odd that an offsite source is considered
 >>(mildly) authoritative.
 >
 >
 > Well, all that stuff IS properly documented in the PickAxe, in the
 > extending Ruby section.  The PickAxe is somewhat poor in that it does
 > cover properly wrapping methods that return new C++ objects (the Zoo
 > and Animal tutorial in SWIG is a top-notch example of all the headaches
 > you can run into on wrapping a complex library).

The online version of the PickAxe has been my main reference. It is
missing a bit of info, generally relating to marking and garbage
collection.

My secondary reference...

 > You also have this, if you haven't read it.
 >
 > http://metaeditor.sourceforge.net/embed/
 >
 > I found it somewhat confusing, but it is probably another source.

... is this one.

This one fills in some of the gaps from the first. It is no literary
masterpiece but it is quite useful.

 >>Okay, so just like an object. Good news. Very elegant and Ruby-ish. :)
 >>Any way to grab the class from the Ruby script? What I really want is
 >>to replace your first line with something like:
 >>
 >>VALUE cFoo = rb_grab_class_from_script("ClassDefinedInScript")
 >>
 >
 >
 > Class names are just constants.
 > If your class is in the global namespace, use:
 >
 > VALUE cFoo = rb_const_get( rb_cObject, rb_intern("YourClass") );
 >
 > If not, replace rb_cObject for the proper module name.

This I didn't know. So class names are basically constants and
can be accessed that way.

 >   VALUE result = rb_protect( wrap_callback, VALUE(&data), &error );

You can do this!? Is this safe? It would seem to work on the idea
that VALUE is always going to be of sufficient size and structure
to hold a pointer directly. Is there any authoritative source that
says: "directly casting a pointer to a VALUE is perfectly fine and
will continue to be supported".

If so, VALUE can be used (effectively) in the same way as a void*,
so there is no need to convert everything into Ruby objects as
I had thought.

If not, I'm not sure this call can be counted on to work reliably
in the future.

 >>The Python docs look decent, I'd just rather not relearn Python again,
 >>I chose Ruby years ago, I'm good with it, and I like it better than
 >>Python! :) But I'd rather move on from LUA if I can...
 >
 > Python is worse at embedding than Ruby is.  So if you have troubles
 > with Ruby, good luck with Python!  On python you don't need to just
 > take care of garbage collecting, but of reference counting.  It is a
 > royal pain if you are doing it manually like you are.

I'll probably give it a shot for interest's sake. Looking closer at the
Python docs that don't seem as strong as first impressions suggest,
although there are some decent examples.

 >>I've spent close to two days on embedding Ruby and can't get the basic
 >>things I've described working.
 >
 > You should be able to get ruby up and running in about a couple of
 > hours (that's all it took me).

Yes, I should (something basic anyway). Unfortunately, I didn't (*).
This is the problem.

When such difficulties arise, they can suggest:
- it is the user's fault; or
- there is a problem with the documentation; or
- the interface is unintuitive; or
- the library itself is buggy.

I shouldn't have to explain why the likelihood of the first reduces
significantly with the number of external libraries the user has
successfully integrated in the past and the number of years they have
been working in software development. Any of the remaining three are
worth bringing to the attention of the dev gods.

Anyway I'm hoping that someone with the requisite knowledge spots these
posts, thinks "hey, perhaps we could look again at issue X" and
something comes of my experiences here. Or perhaps not, but nobody can
say I never mentioned it. Ultimately, the selfish aspect of my motivation
is that someone spots these posts, and dispenses some form of guru-like
wisdom that instantly solves the problems I am having.

Googling some of the error messages I am seeing and issues I am facing
suggest I may not be alone.

(*) - Technically I _did_ in a couple of hours, but it wasn't stable and
crashed randomly, so I tried to figure out what was going wrong. No luck.

 >  Wrapping complex classes that return
 > pointers to other classes and the like, however, is hairy.  But SWIG is
 > there to help now.
 >
 >>I dearly want to be completely wrong.
 >
 > You are.

That was unwarranted.

Anyway, in this exchange a number of issues have come up that an
experienced Ruby user (definitely not a guru though!) completely new
to the embedded interface tripped up on completely. I would suggest
that a good place for these little tips and tricks that keep coming up
would be somewhere near the official documentation, so that the next
person who comes along to play with embedded Ruby can start off
slightly further ahead than I did.

Garth