Question

I know almost no C++ so that's not helping, and my XS isn't much better. I'm creating an XS interface for a C++ library and I have almost all my methods working except one.

The method in Perl should look like this:

$return_data = $obj->readPath( $path );

The method is defined as this the .h file:

int readPath(const char* path, char* &buffer, bool flag=true);

The "buffer" will get allocated if it's passed in NULL.

There's two additional versions of readPath with different signatures, but they are not the ones I want. (And interestingly, when I try and compile it tells me the "candidates" are the two I don't want.) Is that because it's not understanding the "char * &"?

Can someone help with the xsub I need to write?

I'm on Perl 5.14.2.

BTW -- I've also used a typemap "long long int" to T_IV. I cannot find any documentation on how to correctly typemap long long. Any suggestions how I should typemap long long?

Thanks,

Was it helpful?

Solution

I've never dealt with C++ from C or XS. If it was C, it would be:

void
readPath(SV* sv_path)
   PPCODE:
      {
         char*  path   = SvPVbyte_nolen(sv_path, len);
         char*  buffer = NULL;

         if (!readPath(path, &buffer, 0))
            XSRETURN_UNDEF;

         ST(0) = sv_2mortal(newSVpv(buffer, 0));
         free(buffer);

         XSRETURN(1);
      }

Hopefully, that works or you can adjust it to work.


I assumed:

  • readPath returns true/false for success/failure.
  • buffer isn't allocated on failure.
  • The deallocator for buffer is free.

OTHER TIPS

Second part of the question is TYPEMAP for long long (or long long int).

Normally long is at least 32 bits and long long is at least 64. The default typemap for long is T_IV. Perl's equivalent for long long is T_IV, too.

But sometimes, you wan't to reduce warnings for cast. So, you can use T_LONG for long. T_LONG is an equivalent to T_IV but explicitly casts the return to type long. The TYPEMAP for T_LONG is descripted at $PERLLIB/ExtUtils/typemap

With this knowledge you can write you own TYPEMAP for long long int:

TYPEMAP: <<TYPEMAPS
long long int T_LONGLONG

INPUT
T_LONGLONG
  $var = (long long int)SvIV($arg)

OUTPUT
T_LONGLONG
  sv_setiv($arg, (IV)$var);
TYPEMAPS
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top