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

Hi Monks

I m trying to call a C function stored in a library via perlXS. The signature of the C function is as under and the last two parameters are ouput parameters and contain a list

int rcv_msg(char *query, int readlen, char *testHost, char *testPort, +char *prodHost, char *prodPort, char *testMsg, char *prodMsg)

The XS code is as under :-

#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include "const-c.inc" MODULE = REGTEST PACKAGE = REGTEST INCLUDE: const-xs.inc int rcv_msg(query,queryLen,testHost,testPort,prodHost,prodPort,testMsg,pro +dMsg) char *query int queryLen char *testHost char *testPort char *prodHost char *prodPort char *testMsg = NO_INIT char *prodMsg = NO_INIT OUTPUT: testMsg prodMsg RETVAL

The c fuction returns a list value (i.e. the o/p of the query). I m not sure how do i store the list value in XS

the Perl code is as under :-

use ExtUtils::testlib; use REGTEST; local $/ = undef; my $query = "select symbol from SEC where symbol=\'IBM\'\;"; my $queryLen = split//,$query; my $testHost = "pisas392"; my $testPort = 50071; my $prodHost = "pisas392"; my $prodPort = 50071; my ($prodRes,$testRes); ($testRes,$prodRes) = REGTEST::rcv_msg($query,$queryLen,$testHost,$tes +tPort,$pro dHost,$prodPort,$testRes,$prodRes);

Any help is highly appreciated Thanks

Replies are listed 'Best First'.
Re: Return list from C to PerlXS
by Anonymous Monk on Oct 17, 2008 at 09:16 UTC
    Try 'xsubpp yourfile.xs' and you'll see
    XS(XS_REGTEST_rcv_msg) { dXSARGS; if (items != 8) Perl_croak(aTHX_ "Usage: REGTEST::rcv_msg(query, queryLen, testHos +t, testPort, prodHost, prodPort, testMsg, prodMsg)"); { char * int char * char * char * char * char * + testMsg; char * prodMsg; int RETVAL; RETVAL = rcv_msg(query, queryLen, testHost, testPort, prodHost, pr +odPort, testMsg, prodMsg); } XSRETURN(1); }
    XSRETURN(1) means it returns one. So XSRETURN(3) site:search.cpan.org and you'll find some examples, like
    void GetBorders(handle) HWND handle PREINIT: int aBorders [3]; PPCODE: if(SendMessage(handle, SB_GETBORDERS, (WPARAM) 0, (LPARAM) aBorder +s) == TRUE) { EXTEND(SP,3); XST_mIV(0,aBorders[0]); XST_mIV(1,aBorders[1]); XST_mIV(2,aBorders[2]); XSRETURN(3); } else { XSRETURN_UNDEF; }
    or
    void tdxs_wait_for_response() PPCODE: I32 result = EM_OK; I32 sessid = 0; I32 token = 0; char *cnta = NULL; DBCHWAT(&result, cnta, &sessid, &token); EXTEND(SP, 3); if (result != EM_OK) { PUSHs(&PL_sv_undef); PUSHs(sv_2mortal(newSViv(result))); PUSHs(&PL_sv_undef); XSRETURN(3); } PUSHs(sv_2mortal(newSViv(sessid))); PUSHs(sv_2mortal(newSViv(0))); PUSHs(&PL_sv_undef); XSRETURN(3);