Wrapping a C Library: Allocation and duplication issues

Discussion in 'Ruby' started by Justin Bonnar, Sep 13, 2006.

  1. 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/

    --
    Posted via http://www.ruby-forum.com/.
     
    Justin Bonnar, Sep 13, 2006
    #1
    1. Advertising

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

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Sep 13, 2006
    #2
    1. Advertising

  3. 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-forum.com/.
     
    Justin Bonnar, Sep 13, 2006
    #3
  4. 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-forum.com/.
     
    Justin Bonnar, Sep 13, 2006
    #4
  5. Justin Bonnar

    ts Guest

    >>>>> "J" == Justin Bonnar <> 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
     
    ts, Sep 13, 2006
    #5
  6. Justin Bonnar

    Lyle Johnson Guest

    On 9/12/06, Justin Bonnar <> 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.
     
    Lyle Johnson, Sep 13, 2006
    #6
  7. 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-forum.com/.
     
    Justin Bonnar, Sep 13, 2006
    #7
  8. Justin Bonnar

    Lyle Johnson Guest

    On 9/13/06, Justin Bonnar <> 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. ;)
     
    Lyle Johnson, Sep 13, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Grzegorz Stasica
    Replies:
    2
    Views:
    352
    Tobias Schierge
    Feb 12, 2004
  2. Ken
    Replies:
    24
    Views:
    3,949
    Ben Bacarisse
    Nov 30, 2006
  3. chris
    Replies:
    6
    Views:
    1,031
    chris
    Oct 28, 2005
  4. Bjarke Hammersholt Roune
    Replies:
    14
    Views:
    1,222
    Bjarke Hammersholt Roune
    Mar 6, 2011
  5. Replies:
    0
    Views:
    106
Loading...

Share This Page