[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Wrapping a C Library: Allocation and duplication issues

Justin Bonnar

9/13/2006 2:54:00 AM

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://l...

--
Posted via http://www.ruby-....

7 Answers

Joel VanderWerf

9/13/2006 4:49:00 AM

0

Justin Bonnar wrote:
> 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://l...
>

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.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Justin Bonnar

9/13/2006 7:20:00 AM

0

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

--
Posted via http://www.ruby-....

Justin Bonnar

9/13/2006 8:01:00 AM

0

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

--
Posted via http://www.ruby-....

ts

9/13/2006 8:57:00 AM

0

>>>>> "J" == Justin Bonnar <jbonnar@berkeley.edu> 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


Lyle Johnson

9/13/2006 1:52:00 PM

0

On 9/12/06, Justin Bonnar <jbonnar@berkeley.edu> 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.

Justin Bonnar

9/13/2006 4:39:00 PM

0

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

--
Posted via http://www.ruby-....

Lyle Johnson

9/13/2006 5:37:00 PM

0

On 9/13/06, Justin Bonnar <jbonnar@berkeley.edu> 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. ;)