On Sun, 14 Dec 2003, Elias Athanasopoulos wrote:

> Date: Sun, 14 Dec 2003 02:33:04 +0900
> From: Elias Athanasopoulos <elathan / phys.uoa.gr>
> Newsgroups: comp.lang.ruby
> Subject: Re: strange rb_gc_mark error
> 
> On Sun, Dec 14, 2003 at 12:02:27AM +0900, Elias Athanasopoulos wrote:
> > On Sat, Dec 13, 2003 at 10:11:12PM +0900, Yukihiro Matsumoto wrote:
> > > Hi,
> > > 
> > > In message "strange rb_gc_mark error"
> > >     on 03/12/13, Elias Athanasopoulos <elathan / phys.uoa.gr> writes:
> > > 
> > > |I have a pure C function, which may be called arbitrary 
> > > |sequential times. If I call any rb_* function inside, including
> > > |the simple rb_warn(), I get:
> > > |
> > > |BUG] rb_gc_mark(): unknown data type 0x28(0x89965b0) non object
> > > |ruby 1.8.0 (2003-08-04) [i586-linux]
> > > |
> > > |The error occures after a lot of calls; it reminds me the 
> > > |behaviour of a stack overflow, or something.
> > > 
> > > Show us whole program, if possible, to reproduce your error.
> > 
> > I will try, but it is a little bit hard because the C func is called
> > from a C++ method deeply inside a complex inheritance tree.
> > 
> > Things that I can verify now are:
> > 
> > (a) The C func is called with no problem 8000 times.
> > (b) The C func is called for 3000+ and segfaults if I put a
> >     simple rb_warn() inside. Ruby 1.8.0
> > (c) The C func is called for 6000+ and segfaults if I put a
> >     simple rb_warn() inside. Ruby 1.8.1 preview 3.
> 
> Okay, it is my fault. :-(
> 
> While writting a C++ extension for Ruby, I do (almost everywhere):
> 
> static VALUE foo_init (...)
> {
>     Foo *f = new Foo();
>     rb_iv_set (self, "__ptr__", (VALUE) f);
>     return self;
> }
> 
> static VALUE foo_bar (...)
> {
>     Foo *f = (Foo *) rb_iv_get (self, "__ptr__");
>     f->Bar();
>     return self;
> }
> 
> The error ruby reports is on an address of a Foo created pointer.
> If I remove the rb_iv_set() call, ruby executes correctly. But, I
> have to keep the pointer somewhere in order to execute methods of
> the specific class.
> 
> Any ideas?

create a struct to wrap Foo objects with and let ruby handle the object:

  struct FooWrap { Foo *foo; };
  ...
  ...
  VALUE rb_cFooWrap;
  ...
  ...
  static VALUE
  FooWrap_free (FooWrap)
    struct FooWrap *FooWrap;
  {
    delete FooWrap->foo;
    free(FooWrap);
  }
  ...
  ...
  /* defined this as the class 'new' method in Init */
  static VALUE
  rb_cFooWrap_c_new (klass)
    VALUE klass;
  {
    struct FooWrap *FooWrap;
    VALUE obj;
    obj = Data_Make_Struct(klass, struct FooWrap, 0, FooWrap_free, FooWrap);
    return obj;
  }
  ...
  ...
  static VALUE foo_init (...)
  {
      rb_iv_set (self, "foowrap", rb_cFooWrap_c_new);
      return self;
  }

  static VALUE foo_bar (...)
  {
      VALUE foowrap;
      struct FooWrap *FooWrap;
      
      foowrap = rb_iv_get (self, "foowrap");
      Data_Get_Struct(foowrap, struct FooWrap, FooWrap)
      FooWrap->foo->Bar();
      return self;
  }


i don't know if you can wrap c++ class directly since Data_Make_Struct uses
ALLOC internally...

-a
-- 

ATTN: please update your address books with address below!

===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP     :: http://www.ngdc.noaa.gov/stp/
| NGDC    :: http://www.ngdc.noaa.gov/
| NESDIS  :: http://www.nesdis.noaa.gov/
| NOAA    :: http://www.noaa.gov/
| US DOC  :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.  
| Art is everything else.  
|   -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done' 
===============================================================================