I am trying to write an xs interface to an external C library and, since I am learning Perl only for 2 weeks, I have serious problems� I�ll be so happy il somebody could help me ! ! ;-)
Here are my main problems (except my english is so bad !)
In the .h (see below), some C structures are defined.
In Perl, I�ll use hash tables. In .xs, I�ve tried to copy the Perl hash
table in C structures in order to call the C function, and then to copy
back the result in hash tables.
But, when I print the result, I haven�t the same results
for the parameters I wrote in Perl and the parameters passed in the C function
! See inside the code for more explanations�.
I hope you�ll help me and tell what is wrong with my code ! If you don�t understand my problem, just ask me and I�ll try to explain better.
Thanks.
Isabelle.
----------> Here is my .h :
typedef double Float64;
typedef enum {�
} ConvResultT;
typedef struct {
Float64 x ;
Float64 y;
} StereographicCoordinatesT;
typedef struct {
Float64 latitude;
Float64 longitude;
} GeographicCoordinateT;
ConvResultT StereoToGeoCoordinates (
StereographicCoordinatesT
*stereo_coordinate_p,
GeographicCoordinateT
*geographic_coordinate_p);
/* stereo_coordinate_p is data in, geographic_coordinate_p is data out*/
----------> Here is what I�d like to write in Perl
$stereo = {x=>4.2, y=>6.5};
$geo = StereoToGeoCoordinates($stereo) ;
/* or StereoToGeoCoordinates($stereo,$geo) ;
print « geo : latitude = $geo->latitude, longitude
= $geo->longitude\n » ;
---------->Here is what I wrote in my .xs
double
getDouble(HV *hv, char *field) {
SV **svv = hv_fetch(hv, field, strlen(field),FALSE);
SV *sv = *svv;
double res;
if (svv){
if (SvOK(sv)){
return = SvNV(sv);
}
else{
/*undef value*/
croak("Undef value\n");
}
}
else {
croak("No such arg in
hvfetch\n");
}
}
void setDouble(HV *hv,char *field, double val) {
SV **svv = hv_fetch(hv, field, strlen(field),TRUE);
if (svv){
sv_setnv(*svv,val);
}
else {
croak("No such arg in
hvfetch\n");
}
}
MODULE = Util PACKAGE = Util
void
StereoToGeoCoordinates(rv_stereo,rv_geo)
SV *rv_stereo
SV *rv_geo
= NO_INIT
PREINIT:
StereographicCoordinatesT stereo;
GeographicCoordinateT geo;
CODE:
if (SvROK(rv_stereo) && (SvTYPE(SvRV(rv_stereo))
== SVt_PVHV)) {
HV *hv_stereo = (HV*)SvRV(rv_stereo);
HV *hv_geo;
/* Copy perl hash to C structure */
stereo.x = getDouble(hv_stereo,"x");
stereo.y = getDouble(hv_stereo,"y");
/*Here, when I print the result of
getDouble, I have something which looks like an address, */
/*when I print stereo.x, it�s 0!!!!!*/
/*C function call --will write results in geo structure */
StereoToGeoCoordinates(&stereo,&geo);
/*Copy data back into perl structures*/
setDouble(hv_geo,"latitude",geo.latitude);
setDouble(hv_geo,"longitude",geo.longitude);
rv_geo = newRV_inc((SV*)hv_geo);
}
else croak("arg not a hash ref\n");
OUTPUT:
rv_geo
