Wrapping a C Library: Allocation and duplication issues

J

Justin Bonnar

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/
 
J

Joel VanderWerf

Justin said:
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/

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.
 
J

Justin Bonnar

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
 
J

Justin Bonnar

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
 
T

ts

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
 
L

Lyle Johnson

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.
 
J

Justin Bonnar

ts said:
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 said:
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
 
L

Lyle Johnson

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. ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top