I am trying to explain,

Here are the 2 perl subroutines:
sub sub1 {
  my %a ;
  $a {a} = 1 ;
  $a {b} = 2 ;
  foreach (keys %a) {
    print $_, " => ", $a {$_}, "\n" ;
    }
  return \%a ;
  }

sub sub2 {
  my ($h) = @_ ;
  foreach (keys %$h) {
    print $_, " => ", $$h {$_}, "\n" ;
    }
  }
+++++++++++++++++++++++++++++++++
In XS:
  PREINIT:
    int count ;
    SV *retval ;
    HV *hv ;
    SV **elem ;
  CODE:
    dSP ;
    ENTER ;
    SAVETMPS ;
    PUSHMARK (SP) ;
    PUTBACK ;
    count = call_pv ("sub_::sub1", G_ARRAY | G_NOARGS | G_EVAL) ;
    SPAGAIN ;
    if (SvTRUE (ERRSV)) {
printf ("An error occured in the Perl preprocessor: %s\n", SvPV_nolen (ERRSV)) ;
      }
    else {
      printf ("Nb values returned: %d\n", count) ;
      retval = POPs ;
      if (! SvROK (retval) || SvTYPE (SvRV (retval)) != SVt_PVHV) {
        croak ("Return value is not a hash reference\n") ;
        }
      else {
        hv = (HV*) SvRV (retval) ;
        }
      }
newRV ((SV*) retval) ; //OK
    FREETMPS ;
    LEAVE ;
    elem = hv_fetch (hv, "a", 1, FALSE) ;
    ENTER ;
    SAVETMPS ;
    PUSHMARK (SP) ;
    XPUSHs (sv_2mortal (newRV ((SV*) hv))) ;
    PUTBACK ;
    count = call_pv ("sub_::sub2", G_DISCARD | G_EVAL) ;
    SPAGAIN ;
    FREETMPS ;
    LEAVE ;

Like it is here, it should partially work, at least it gives me the correct display due to sub2.
Notice the newRV before the FREETMPS !!!
If I remove it, it does not work at all, 1) the hv_fetch generate a
segmentation fault, 2) the sub2 gives an error:
Attempt to free unreferenced scalar: SV 0x8941998, Perl interpreter: 0x87b9008 at ./test.pl line 13

Somethnig does not make sense to me !!!
I do not get the refernce properly for sure, but why ?

Regards

Patrick Dupre wrote:
Rob Dixon wrote:

It would be nice to have been told the symptoms you are getting, as your code
looks basically correct.

All I can see that is wrong is that you need to add  PUSHMARK(SP) before the
call to the Perl subroutine to mark the end of any parameters you push onto the
stack.

Presumably you have had the XS subroutine working at some point? In which case
you need to look at the last thing you added that stopped it working. In
addition it would be nice to see proper variable names: using things like 'ptr'
is bad practice, and it is even worse here where you have variables with
multiple levels of both C and Perl indirection and it is easy to get confused.

I am trying to investigate more, but, one problem seems to that that the
SvTYPE (ret) is 3, ie that it is a RV reference when it should be a
hash reference. Am I correct ?

(Please bottom-post your responses. Thank you.)

No, your perl subroutine is returning a hash reference, so you should see an RV.
Dereference that using SvRV to get your HV. It should look something like this

   retval = POPs;

   if (! SvROK(retval) || SvTYPE(SvRV(retval)) != SVt_PVHV) {
     croak("Return value is not a hash reference");
   }

   hash = (HV*)SvRV(retval);

   ref_elem = hv_fetch(hash, "a", 1, FALSE);

which is pretty much what you had in the first place, so I'm still not sure what
your problem is. Can you describe what symptoms you're getting please?

Rob



--
---
==========================================================================
 Patrick DUPRÉ                      |   |
 Department of Chemistry            |   |    Phone: (44)-(0)-1904-434384
 The University of York             |   |    Fax:   (44)-(0)-1904-432516
 Heslington                         |   |
 York YO10 5DD  United Kingdom      |   |    email: [EMAIL PROTECTED]
==========================================================================
-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/

Reply via email to