mitchm has asked for the wisdom of the Perl Monks concerning the following question:

Hey there,

I'm trying to use perlxs to call a proprietry C library from my perl scripts.
I've gone through the tutorial and such, I've successfully got the extension compiling and I can use it in my perl script and even call a couple of the functions i've already defined in the .xs file.

The problem, however, is I can't figure out how to return a variable from one of the functions. Every way I define it in the .xs file either doesn't compile, or compiles and segfaults when i run the perl script.

The C excerpt I use to call this function is as follows :

char sError[BUFFLEN]; QAErrorMessage(error_code, sError, BUFFLEN);
BUFFLEN being defined as 256 or whatever.
It's supposed to return a nice, helpful error message in sError...

The function doesn't seem to like being called with a char *, and I have no idea how to make xs return the sError to perl as a normal scalar.

Any suggestions would be much appreciated

Replies are listed 'Best First'.
Re: Perlxs help please
by Ovid (Cardinal) on Oct 01, 2003 at 03:57 UTC

    I don't know XS very well, but if you want to create a scalar from a char * and return it to Perl, here's a way to do it in Inline (which is much easier than XS):

    #!/usr/local/bin/perl use strict; use warnings; use Inline C => <<'END_OF_C_CODE'; SV * get_string() { char string[] = "test"; SV *result = newSVpv(string, 0); return result; } END_OF_C_CODE my $string = get_string(); print $string;

    (It's a bit verbose for clarity)

    Cheers,
    Ovid

    New address of my CGI Course.

Re: Perlxs help please
by tachyon (Chancellor) on Oct 01, 2003 at 03:21 UTC

    perlman:perlxs OUTLIST RETVAL SV* newSVpv() depending on your context.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      This is what I tried, but it's failing with with incompatible types

      in the .h file:
      void QAErrorMessage(int, char *, int);

      in the .xs file:
      void QAErrorMessage(err_code, ret_error, bufflen) int err_code SV* ret_error int bufflen OUTPUT: ret_error

      I'm bviously missing something

        How do you want to call the C function out of Perl? I think you are looking for something like:

        SV * err_msg( code ) int code; INIT: char sError[255]; CODE: QAErrorMessage( code, sError, 255 ); SV *result = newSVpv(sError, 0); OUTPUT: result

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        Let me bold some things for you ;)
        void
        QAErrorMessage(err_code, ret_error, bufflen)
                int     err_code
                SV*     ret_error
                int     bufflen
            OUTPUT:
                ret_error
        
        void and OUTPUT do not mix (void means no output). You should try something like
        void QAErrorMessage(error_code) CASE: int err_code PREINIT: int bufflen = 256; char ret_error[bufflen]; PPCODE: { QAErrorMessage(err_code, ret_error, bufflen); XPUSHs(sv_2mortal( newSVpvn(ret_error,bufflen) )); }

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.