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
=====