> -----Original Message-----
> From: Mik Firestone [mailto:[EMAIL PROTECTED]
> Sent: Thursday, July 29, 2004 9:00 AM
> To: [EMAIL PROTECTED]
> Subject: Returning reference to C structures
> 
> 
> I am just looking for a URL or an example of how to return a 
> reference to a C
> structure to perl.  I have read the Cookbook, and I can get 
> my code to work if
> I actually create a blessed reference.  I would prefer to 
> bless it - I just
> want a reference that I can later pass to other C functions.


Here's how I do it.  I've got a perl object that I want to store some C context in (so 
it can maintain state between calls), so I create a "_context" slot in the $self 
object like so:

      HV *self_hash = (HV*) SvRV(self);
      SV **fetched = hv_fetch(self_hash, "_context", 8, 1);
      if (fetched == NULL)
        croak("Couldn't create the _context slot in $self");

      sv_setiv(*fetched, (IV) my_struct_pointer);
      SvREADONLY_on(*fetched);

The SvREADONLY_on() call is important because I want this thing to be immutable in 
perl-land.  Then when I want to retrieve the context struct again, I use a little 
helper function:

  /* A pure-c function, not visible from perl */
  context_struct *get_context_struct (SV *self) {
    HV *self_hash = (HV*) SvRV(self);
    SV **fetched = hv_fetch(self_hash, "_context", 8, 0);
    if (fetched == NULL)
      croak("Couldn't fetch the _context slot in $self");
    
    return (context_struct *) SvIV(*fetched);
  }
  ...
  /* An XS function visible to perl */
  void
  foo( self )
       SV   * self
  CODE:
    {
      context_struct *c = get_context_struct(self);
      ...
    }


Theoretically I could put this helper function in a typemap too, to make things look a 
little cleaner.

 -Ken

Reply via email to