in reply to perlxs INTERFACE problem

Hi Fiftyvolts,

That XS file compiles fine for me on Win32 (perl 5.8.8) - and the resultant module tests fine.

I do note that I'm getting a slightly different C file. Here it is (in full):
/* * This file was generated automatically by ExtUtils::ParseXS version +2.17 from the * contents of Test.xs. Do not edit this file, edit Test.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "Test.xs" #include "EXTERN.h" #include "perl.h" #include "XSUB.h" int add_one(int i) { return i + 1; } int add_two(int i) { return i + 1; } #ifndef PERL_UNUSED_VAR # define PERL_UNUSED_VAR(var) if (0) var = var #endif #line 28 "Test.c" XS(XS_Test_add_interface); /* prototype to pass -Wmissing-prototypes * +/ XS(XS_Test_add_interface) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif dXSFUNCTION(int); if (items != 1) Perl_croak(aTHX_ "Usage: %s(%s)", "Test::add_interface", "i"); PERL_UNUSED_VAR(cv); /* -W */ { int i = (int)SvIV(ST(0)); int RETVAL; dXSTARG; XSFUNCTION = XSINTERFACE_FUNC(int,cv,XSANY.any_dptr); RETVAL = XSFUNCTION(i); XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); } #ifdef __cplusplus extern "C" #endif XS(boot_Test); /* prototype to pass -Wmissing-prototypes */ XS(boot_Test) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif char* file = __FILE__; PERL_UNUSED_VAR(cv); /* -W */ PERL_UNUSED_VAR(items); /* -W */ XS_VERSION_BOOTCHECK ; { CV * cv ; cv = newXS("Test::add_two", XS_Test_add_interface, file); XSINTERFACE_FUNC_SET(cv,add_two) ; cv = newXS("Test::add_one", XS_Test_add_interface, file); XSINTERFACE_FUNC_SET(cv,add_one) ; } XSRETURN_YES; }
Btw, note that *both* add_one() and add_two() add *one*. (Had me stumped for a moment when I was testing the module, because I expected add_two() to add two and hadn't actually read the relevant code ... silly me :-)

Cheers,
Rob
Afterthought: Are you using the same compiler that was used to build perl ? If not, then could it be that your 'cc' is incompatible with the C code that's being generated ?

Replies are listed 'Best First'.
Re^2: perlxs INTERFACE problem
by Fiftyvolts (Novice) on Nov 15, 2007 at 12:37 UTC

    Yeah it's the same compiler. Something else must be wrong... maybe I'm missing an option. I'm going to keep trying.

    As for add_one/add_two I ment that one was the first and one was the second, not what they return >.< Silly me, I think they get the award for worst function names of the day.

      Ok I think I have the solution. It appears to be a combination of my compiler and my XSUB.h file (which I guess is really a statement of my perl version 5.6.1)

      So 5.6.1 defines the macro that extracts the C function to call for a particular invocation of the perl interface something to the effect of this: (I expanded some of the macros for clarity)

      XSFUNCTION = ((ret (*cv)())(XSANY.dptr));

      Of course the cast shown above grossly violates the C standard for abstract declarators (no identifiers should be present, a.k.a. "cv"). The reason for this is because the header is reusing the same code that declares XSFUNCTION (which needs an identifier). cc barfs when it reaches the cast.

      I took a look at the XSUB.h in 5.8.8, and sure enough it's been corrected to not include an identifier. I must not be the first person with this problem :)

      If you are unfortunate enough to not be able to upgrade your version of perl for some reason and you still need or want to get this to work here's what you can add at the beginning of your XS file to fix things:

      #undef XSINTERFACE_FUNC #define XSINTERFACE_FUNC(ret,cv,f) ((ret (*)())(f))

      And that's all folks. Thanks for the advice :)

      Yeah it's the same compiler

      Seems an odd error to be getting. I just tried it out on linux and it all works fine there, too.

      What version of perl are you running ? I notice, too, that my C file is being generated by ExtUtils::ParseXS-2.17. Maybe that's the key to success ?

      Update: Then again ... on linux, the C file was generated by xsubpp-1.9508.

      Cheers,
      Rob