Re: Stringwise comparisons (Inline::C)
[email protected] ("Sisyphus")
| Newsgroups | perl.inline |
|---|---|
| Message-ID | <91BBBFFE56F34F23BF3733C77D7FF2A7@desktop2> |
----- Original Message -----
From: "David Oswald"
> sub compare {
> return $_[0] cmp $_[1];
> }
>
> .... A C stub:
>
> int compare( SV* left, SV* right ) {
> int result;
> // Compare the two SV's stringwise.
> return result;
> }
>
>
> ....and....
>
> sub lessthan {
> return $_[0] lt $_[1];
> }
>
> A C stub:
>
> int lessthan( SV* left, SV* right ) {
> int result;
> // Less-than compare the two SV's stringwise.
> return result;
> }
>
I think a callback to a perl subroutine is what you're after. See the
perlcall documentation.
The following demo is taken from one of the examples in the perlcall docs -
but it prints out the result of the comparison, rather than returning it.
I couldn't quickly modify it to return the value .... though it shouldn't be
that difficult. I think you'll need to replace "dSP" with "dXSARGS" and then
somehow XSRETURN the value off the stack. I'll leave my quick and wrong
attempt in there - it simply returns 'hello'.
There might even be some example in perlcall that demonstrates how to
correctly return a value - I didn't look all the way thru it.
##############################
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1;
use Inline C => <<'EOC';
void call_Compare(char * a, char * b) {
dSP;
int count;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(a, 0)));
XPUSHs(sv_2mortal(newSVpv(b, 0)));
PUTBACK;
count = call_pv("Compare", G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Big trouble\n");
printf ("Comparison of %s and %s yields %d\n", a, b, POPi);
PUTBACK;
FREETMPS;
LEAVE;
}
void return_Compare(char * a, char * b) {
dXSARGS;
int count;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(a, 0)));
XPUSHs(sv_2mortal(newSVpv(b, 0)));
PUTBACK;
count = call_pv("Compare", G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Big trouble\n");
PUTBACK;
FREETMPS;
XSRETURN(1);
}
EOC
call_Compare ('hello', 'world');
call_Compare ('hello', 'hello');
call_Compare ('hello', 'hell');
print return_Compare ('hello', 'world'), "\n";
print return_Compare ('hello', 'hello'), "\n";
print return_Compare ('hello', 'hell'), "\n";
sub Compare {
return $_[0] cmp $_[1];
}
##############################
Cheers,
Rob