I’m writing a wrapper for a C library [1] written in a very object
orientated style. All of the “classes” are created with a
librdf_new_classname method which acts almost the same as Ruby’s
Class#new.
The problem I’m having is cleanly separating allocation from
initialization. Since most of the class construction functions require
arguments to initialize the object, I can’t define separate alloc and
initialize functions.
The only option I see is to use Ruby 1.6 style code and define a
Klass.new method for my classes. The problems with this is it prevents
clean subclassing and object cloning. Is there a better way to wrap the
library?
Thanks,
Justin
[1] http://librdf.org/
Justin B. wrote:
The only option I see is to use Ruby 1.6 style code and define a
Klass.new method for my classes. The problems with this is it prevents
clean subclassing and object cloning. Is there a better way to wrap the
library?
Thanks,
Justin
[1] http://librdf.org/
What about calling librdf_new_classname() from the initialize method,
and not doing anything special in the alloc function?
README.EXT says:
To define and undefine the `allocate’ class method,
void rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass));
void rb_undef_alloc_func(VALUE klass);
func have to take the klass as the argument and return a newly
allocated instance. This instance should be empty as possible,
without any expensive (including external) resources.
The ary_alloc function for Array, for example, does not allocate storage
for the actual C array of VALUE. It only allocates the basic RArray
object, with a null ptr. Then rb_ary_initialize() looks at the arguments
and allocates storage for ptr, as needed.
I don’t think that approach will work: librdf_new_classname() allocates
the memory it needs and returns a pointer to the structure. Part of the
problem is that struct may be different depending on the arguments
passed in (a particular storage backend, etc) and that the C header
files don’t define the internals of the structures themselves (so I get
incomplete type errors during compilation.
-Justin
Acutally, I’m not a C or Ruby/C guru, but would any of the following be
possible?
-
Wrapping a null pointer in the allocation function, and then modifying
the DATA object to use the pointer returned by the
librdf_new_classname() call.
-
Creating a pointer to the data structure, and then setting it’s value
to the pointer returned by the librdf_new_classname() call.
The following code compiles and runs, but doesn’t seem to work correctly
(other functions that access the C structure wrapped by the object
behave strangely.)
static VALUE URI_alloc(VALUE klass)
{
librdf_uri* uri;
return Data_Wrap_Struct(klass, 0, librdf_free_uri, uri);
}
static VALUE URI_initialize(VALUE self, VALUE uri_string)
{
librdf_uri* uri;
Data_Get_Struct(self, librdf_uri, uri);
uri = librdf_new_uri(World, StringValuePtr(uri_string));
return self;
}
Thanks,
Justin
“J” == Justin B. [email protected] writes:
J> The following code compiles and runs, but doesn’t seem to work
correctly
J> (other functions that access the C structure wrapped by the object
J> behave strangely.)
Look at ruby-1.8.5/ext/dbm/dbm.c, in the ruby source, to see an example
how you can do this (fdbm_alloc(), free_dbm() and fdbm_initialize())
Guy Decoux
On 9/12/06, Justin B. [email protected] wrote:
I’m writing a wrapper for a C library [1] written in a very object
orientated style…
Just curious: Are the Ruby bindings that come with Redland just not
suitable for your project? I’m wondering why you’re re-inventing the
wheel here.
ts wrote:
Look at ruby-1.8.5/ext/dbm/dbm.c, in the ruby source, to see an example
how you can do this (fdbm_alloc(), free_dbm() and fdbm_initialize())
Thanks, this is exactly what I was looking to due.
Lyle J. wrote:
Just curious: Are the Ruby bindings that come with Redland just not
suitable for your project? I’m wondering why you’re re-inventing the
wheel here.
The RDF-Redland binding is outdated and decidedly un-ruby-like. The
other problem is the SWIG binding for Redland doesn’t expose all of the
functions I wanted to access. In addition to wrapping Redland I need to
get at some of the lower level functions from Rasqal.
We’re also planning on building an Ontology-aware level above Redland,
with goals similar to that of the (now-defunct) Semitar project and want
to get the lowerlevel code right before working on that. Mixing the
existing binding with higher-level C code would be a little ugly - we’d
prefer to keep the lower level code in C.
-Justin
On 9/13/06, Justin B. [email protected] wrote:
The RDF-Redland binding is outdated and decidedly un-ruby-like. The
other problem is the SWIG binding for Redland doesn’t expose all of the
functions I wanted to access. In addition to wrapping Redland I need to
get at some of the lower level functions from Rasqal.
We’re also planning on building an Ontology-aware level above Redland,
with goals similar to that of the (now-defunct) Semitar project and want
to get the lowerlevel code right before working on that. Mixing the
existing binding with higher-level C code would be a little ugly - we’d
prefer to keep the lower level code in C.
Cool. I hope that you’ll share when you’re done. 