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
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.