----- Original Message ----- From: <[EMAIL PROTECTED]>
To: <inline@perl.org>
Sent: Friday, March 23, 2007 6:19 AM
Subject: structs with Inline::C



Hi  everyone,
I am new to inline and am using Inline::C to embed C in my perl code. I am trying to return a struct from a C subroutine back to the perl caller. How do I deal with structs when I use Inline::C? Any help would be appreciated.


You might be able to make use of Inline::Struct from CPAN. It has apparently been abandoned by its author and, IIRC, there are bugs with its handling of nested structs - but it should work reliably for simpler cases. See 'perldoc Inline::Struct' and the module's test scripts for examples of usage.

Also see the "Object Oriented Inline" example in 'perldoc Inline::C-Cookbook'. Along similar lines is this script which I happened to have lying around:

------------------------------------
use warnings;
package My_struct;

use Inline (C => Config =>
           BUILD_NOISY => 1,
           );

use Inline C => <<'EOC';

    typedef struct {
      char * suit;
      int value;
      } Card;

SV * create_struct(SV * s, SV * v) {
    Card * cptr;

    New(123, cptr, sizeof(Card), Card);
if(cptr == NULL) croak("Failed to allocate memory in create_struct function");

    cptr->suit = SvPV_nolen(s);
    cptr->value = SvIV(v);
    return sv_setref_pv(newSViv(0), "My_struct", cptr);
/*******************************************************
    Alternatively, if you don't want to bless the object
    into package My_struct (in which case you'll have to
    call DESTROY() explicitly):
    return sv_setref_pv(newSViv(0), Nullch, cptr);
*******************************************************/
}

void deref_ref(SV * p) {
    Inline_Stack_Vars;

    Inline_Stack_Reset;
    Inline_Stack_Push(newSVpv(((Card *)SvIV(SvRV(p)))->suit, 0));
    Inline_Stack_Push(newSViv(((Card *)SvIV(SvRV(p)))->value));
    Inline_Stack_Done;
    Inline_Stack_Return(2);

}

void DESTROY(SV * p) {
     printf("Destroying ...");
     Card* c = (Card *)SvIV(SvRV(p));
     Safefree(c);
     printf("...destroyed\n");
}


EOC

for(1..500) {
$x = ('Hearts', 'Spades', 'Clubs', 'Diamonds')[rand(4)];
$y = int(rand(13)) + 1;

$p = create_struct($x, $y);

@members = deref_ref($p);
print "@members\n";
}
------------------------------------

There are of course, other ways to do it. For example you could have the struct returned to perl as a hash reference (HV*).

Cheers,
Rob

Reply via email to