Forum: Ruby Inheritance from c

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Phil J. (Guest)
on 2006-06-05 19:32
(Received via mailing list)
Hi All,

I'm messing about with inheritance from my C application but can't get
it to
work properly. Here is a quick overview of what I want to achieve:

class Hello should parent Helloworld. Both use Data_Wrap_Struct to wrap
up
and struct whos memory is allocated with ALLOC. Silly example:

    struct Hello_struct {
        VALUE name;
    }

    struct Helloworld_struct {
        VALUE count;
    }

The trouble is when I try to call a function from a Helloworld instance
that
reads/writes to a copy of the Hello_struct I get a segfault. This
implies to
me that memory is not being allocated for Hello_struct. Do I have to
tell
Heloworld that space for Hello needs to be allocated? If so how?

Confused,
Phil
Joel VanderWerf (Guest)
on 2006-06-05 23:30
(Received via mailing list)
Phil J. wrote:
>     }
>
>     struct Helloworld_struct {
>         VALUE count;
>     }
>
> The trouble is when I try to call a function from a Helloworld instance that
> reads/writes to a copy of the Hello_struct I get a segfault. This implies to
> me that memory is not being allocated for Hello_struct. Do I have to tell
> Heloworld that space for Hello needs to be allocated? If so how?

I'm not sure I understand, but it sounds like you want your Helloworld
instances to have both a Hello_struct and a Helloworld_struct as their
data? And you want instance methods of the Hello class, when called on a
Helloworld object, to operate on an inherited Hello_struct?

This won't work, unfortunately. Ruby T_DATA objects have only one data
pointer. They don't inherit data pointers from superclasses. You need to
manage the inheritance of C structs somehow, possibly by embedding the
Hello_struct members (or embed the struct itself) inside of
Helloworld_struct:

    struct Helloworld_struct {
        VALUE name;
        VALUE count;
    }

If you do this, then Hello methods defined in C just have to cast the
data pointer to a Hello_struct *, and can then access the "name" member.

I wrote the cgen/cshadow library (on RAA) to generate C code in this
way, based on pure-ruby attribute declarations and "in-line" C code.
This is the examples/inherit-example.rb, which I think is included in
the download:

=====

require 'cgen/cshadow'

class Parent
  include CShadow

  shadow_attr_accessor :ruby_str => String
  shadow_attr_accessor :c_int => "int c_int"
end

class Child < Parent
  shadow_attr_accessor :obj => Object # VALUE type
end

Parent.commit
  # we're done adding attrs and methods, so make.

x = Child.new
x.ruby_str = "foo"
x.obj = [1,2,3]
x.c_int = 3

p x
# ==> #<Child:0xb7ba96f4 ruby_str="foo", c_int=3, obj=[1, 2, 3]>

=====

The generated code for the Child class ends up looking like this:

typedef struct Child_Shadow {

    /* Parent_Shadow members */
    VALUE self;
    VALUE ruby_str; // String;
    int c_int;

    VALUE obj; // Object;
} Child_Shadow;

=====

(The "self" member can be very useful--you can get back to the ruby
object from the shadow struct.)

See the other examples for samples of method definitions using in-line C
code. A very brief snippet from complex.rb:

=====

class MyComplex < Numeric
  include CShadow

  shadow_attr_accessor :re => "double re", :im => "double im"

  define_c_method(:abs) do
    include "<math.h>"
    returns "rb_float_new(sqrt(pow(shadow->re, 2) + pow(shadow->im,
2)))"
  end
end

=====
Phil J. (Guest)
on 2006-06-06 13:31
(Received via mailing list)
On Tue, Jun 06, 2006 at 04:27:36 +0900, Joel VanderWerf wrote:
> Phil J. wrote:

[ ..snip.. ]

>
>     struct Helloworld_struct {
>         VALUE name;
>         VALUE count;
>     }

This solved the problem, thanks. I'd made the assumption that Ruby would
build and manage the parent for me by calling new on it.

> I wrote the cgen/cshadow library (on RAA) to generate C code in this
> way, based on pure-ruby attribute declarations and "in-line" C code.
> This is the examples/inherit-example.rb, which I think is included in
> the download:

I had a quick go with this, an excellent tool, very powerful. I would
certainly consider using it for guideline code in the future!

Thanks for your help,
Phil
This topic is locked and can not be replied to.