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

Regarding question2, ulpcallback is a structure of type ulp_callback, How to declare it in typemap file??

for constant char * ,i have added a code in typemap file which looks like

const char *    T_PV

Simillarly how can i declare struct ulp_callback ulpcallback in typemap??

ulpcallback is a datatype in one of my C function. To call that function from perl, i have added a subroutine in .xs file.which looks like.
int f1(a,b,c) int a int b ulpcallback c OUTPUT: RETVAL
when i try to compile it ,it is giving an error that,Error: 'ulpCallback' not in typemap in Mytest2.xs, line 26

here ulpCallback is of type struct ulp_Callback (in C ). I want to declare that in typemap file .How to do that?? I am not familiar to perlxs..and i have no idea abt T_PV etc. Plz help me regarding this.

I added ulpCallback in typemap file as

 ulpCallback T_PTROBJ

Now its not giving that error,But after running make it shows an error Mytest2.c:164: error: conversion to non-scalar type requested Any help regarding this??? Hi all,

My C function expects an array(single dimension)as a parameter,how to declare it in .xs file??

int f1(a,b,c[LEN]) int a int b unsigned char c[LEN] OUTPUT: RETVAL

This gives an error saying that invalid declaration of cLEN.Plz help me.

Replies are listed 'Best First'.
Re: perlxs help
by cdarke (Prior) on Jan 17, 2011 at 10:04 UTC
    In C a parameter of
    unsigned char c[MAX_LEN1][MAX_LEN2]
    is mis-leading, because the first dimension of an array (MAX_LEN1) is ignored at the calling interface, only the second has any meaning. Having said that though, it appears that XS will not accept a multi-dimension array, so use something like this:
    #define MAX_LEN2 1024 int function1(a,b,p) int a unsigned short b unsigned char *p CODE: unsigned char (*c)[MAX_LEN2] = (unsigned char (*)[MAX_LEN2])p; OUTPUT: RETVAL


    Update: I notice that you have added a question 2. I can't answer that, but you should consider just what a "multi-dimensional array" is. Pedantically neither C nor Perl support that: C uses an array of pointers and Perl an array of references. To keep it simple you might consider breaking it down first into an array and then the type of each element (a pointer or a reference).
      Thank you ver much:)
Re: perlxs help
by kejohm (Hermit) on Jan 17, 2011 at 11:36 UTC

    Based on your function declaration, I'm guessing that you want to pass in an array of strings. You will need to instead pass a reference to an array containing strings when calling the function from Perl, then extract the strings from the Perl array and insert them into a C array. Maybe something like this (untested):

    int function(a,b,sv) int a; unsigned short b; SV * sv; INIT: unsigned char ** c; // check if scalar is a reference and is referencing an array if(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV){ // dereference array AV * av = (AV*)SvRV(sv); // get highest array index I32 c_len = av_len(av); // allocate array c = (unsigned char **)malloc(len + 1); // loop through array for(int i = 0; i <= c_len; i++){ // store string in C array c[i] = (char*)SvPV_nolen((SV*)*av_fetch(av, i, 0)); } } OUTPUT: RETVAL

    Check out these various manpages regarding the Perl internals and API for more info:

    Regarding your 2nd question, callbacks in Perl are simply scalar values, holding references to subroutines, that you pass to your XS functions, and then call using the appropriate Perl functions. See the perlcall manpage for more info.

    Update: Links fixed.

Re: perlxs help
by pajout (Curate) on Jan 17, 2011 at 09:48 UTC
    I have not seen xs for many years, but if I remember correctly, there is no concept of two-dimensional arrays. Declare one-dimensional array of MAX_LEN1*MAX_LEN2 and use arithmetic to transform that index to/from two indices.