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/