Hi All,

I'm a beginner at XS and need to interface with some MS specific code
written in C/COM. I initially thought of trying out some example codes
at

http://world.std.com/~swmcd/steven/perl/pm/xs/tools/
which I thought was pretty well written.

I use VC++6.0 compiler, ActiveState Perl distribution(Rev5, Ver6, SubV
1), and have the following directory hierarchy.

--test
   |--src--->test.c, test1.c
   |--include-->test.h
--Glue
   |
   |--test-->Makefile.PL, Test.c, test.pl
 
I created (using h2xs), a module/package named Glue:Test for test.h
I then hand edited the Makefile.PL to have in its include path my C
header

My Makefile.PL, then looks like

use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'              => 'Glue::Test',
    'VERSION_FROM'      => 'Test.pm', # finds $VERSION
    'PREREQ_PM'         => {}, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM => 'Test.pm', # retrieve abstract from module
       AUTHOR     => 'A. U. Thor <[EMAIL PROTECTED]>') :
()),
    'LIBS'              => [''], # e.g., '-lm'
    'DEFINE'            => '', # e.g., '-DHAVE_SOMETHING'
    'INC'               => '-I..\..\test\include', # e.g., '-I.
-I/usr/include/other'
        # Un-comment this if you add C files to link with later:
     'OBJECT'           => 'Test.o ..\..\test\src\test1.o', # link all
the C files too
);

My test1.c contains two subroutines that I write XS wrappers for:

#include "test.h"
double hypotenuse(double a, double b)
{
        return (a*a+b*b);
}

double r2p(double x, double y, double *theta)
{
        double retval = 0;
        *theta = (y*y-x*x);
        retval = x*x + y*y;
        return retval;
}

My corresponding XS file Test.xs is

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "test.h"


MODULE = Glue::Test             PACKAGE = Glue::Test            

PROTOTYPES: ENABLE

double
hypotenuse(x,y)
        double x
        double y

double 
r2p(x,y,theta)
        double x
        double y
        double theta = NO_INIT
        CODE:
                RETVAL = r2p(x,y,&theta);
        OUTPUT:
                RETVAL
                theta

void 
r2p_list(x,y)
        double x
        double y
        PREINIT:
        double r;
        double theta;
        PPCODE:
                r = r2p(x,y,&theta);
        EXTEND(SP,2);
        PUSHs(sv_2mortal(newSVnv(r)));
        PUSHs(sv_2mortal(newSVnv(theta)));



I can compile it fine, and my test.pl to test it looks like:

use Test;
BEGIN { plan tests => 1 };
use Glue::Test;
ok(1); # If we made it this far, we're ok.

#########################

# Insert your test code below, the Test module is use()ed here so read
# its man page ( perldoc Test ) for help writing this test script.
print Glue::Test::hypotenuse(3,4), "\n";
my $theta;
my $r = Glue::Test::r2p(3,4,$theta);
print "$r, $theta\n";

($r, $theta) = Glue::Test::r2p_list(3,4);
print "r2p_list: $r, $theta\n";


Funnily, my output to this test code is:

1..1
ok 1
25
21036340, 7
r2p_list: 21036348, 7

It appears that the return value somehow gets messed up in the second
case,
Note that y*y-x*x seems to be fine, but not the return value.

Has anybody noticed this on Win32? Do you know where I could be going
wrong?

Thanks,
Hari 

Reply via email to