Re: Extending Moose with Inline C?

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
Zbigniew,

You should be able to do this:

package Net::Packet::EraApi;
use Moose;
use ERAAPI2Inline;

has [ qw( OpRef MsgType Operation DataSize data ) ] => (is => 'rw');

sub decode_headers {
     my ( $class, $params ) = @_;
     my $self = $class->new;
     ERAAPI2Inline::Framedecode( $params->{packet}, $self );
     return $self;
}

1;

It is not ideal as it bypasses all the Moose constructor and  
initializer goodness, however since you seem to be unpacking a C  
struct of some kind you wouldn't have been able to do that anyway.

- Stevan



On Jan 13, 2009, at 11:14 AM, Zbigniew Lukasiak wrote:

> Thanks for all the replies,
>
> Apparently this will take longer time - as it seems it is not the
> highest priority right now - but I do find it interesting so I'll try
> to continue it.
>
> On Fri, Jan 9, 2009 at 6:58 PM, Stevan Little
> <[email protected]> wrote:
>> Zbigniew,
>>
>> Well, if you are creating the objects with C, this might be tricky,  
>> but can
>> be worked around. If you are writing/reading data from C-based  
>> accessors,
>> this is still a little tricky but easily worked around. If you just  
>> need to
>> call methods which are not accessors or constructors, but are  
>> written in C,
>> then this will be no problem at all.
>
> For now I have the following:
>
> package Net::Packet::EraApi;
> use base 'Class::Accessor';
> __PACKAGE__->mk_accessors(qw( OpRef MsgType Operation DataSize  
> data ) );
>
> use warnings;
> use strict;
> use ERAAPI2Inline;
>
> .
> .
> .
> sub decode_headers {
>    my ( $class, $packet ) = @_;
>    my %frame;
>    my $f_ref = \%frame;
>    ERAAPI2Inline::Framedecode( $packet, $f_ref );  # this is the  
> Inline builder
>    return bless $f_ref, $class;
> }
>
> So I create the object with 'ecode_headers' and in it I add entries to
> it's data hash with an Inline C function.  The measurements of the
> overheads need to wait - but this is what I was asked to do.
>
>
> The C Inline function in ERAAPI2Inline is:
>
> void* Framedecode(SV* packet, SV* hash_ref) {
>    HV* hash;
>    void* pkt;
>    STRLEN pktlen;
>    struct era_hdr* era_hdr;
>
>    hash = (HV*) SvRV( hash_ref );
>    pkt = SvPV(packet, pktlen);
>    era_hdr = pkt;
>
>    hv_store(hash, "OpRef",     5, newSViv(htonl(era_hdr->opref)), 0);
>    hv_store(hash, "MsgType",   7, newSViv(era_hdr->msgtype), 0);
>    hv_store(hash, "Operation", 9, newSViv((era_hdr->operation)), 0);
>    hv_store(hash, "DataSize",  8, newSViv((era_hdr->datasize)), 0);
>    if(pktlen >= era_hdr_len + era_hdr->datasize )
>        hv_store(hash, "data",  4, newSVpv(pkt+era_hdr_len,
> pktlen-era_hdr_len), 0);
>    else
>        hv_store(hash, "data",  4, &PL_sv_undef, 0);
>    return;
> }
>
>
> Apparently with Class::Accessor this works.
>
> I was also thinking about the Marco Fontani's and Chris Prather's
> proposals of doing:
>
> Net::Packet::EraAp->new(%{ ERAAPI2Inline::Framedecode( $packet ) } );
>
> (with a small change to the C function) - this looks like simple
> workaround and I'll need to check it.  I think this would trigger the
> type checkers in Moose and probably that would mean too much overhead
> though.
>
>
> Cheers,
> Zbigniew
> http://brudnopis.blogspot.com/
> http://perlalchemy.blogspot.com/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.