Erland Sommarskog <[EMAIL PROTECTED]> writes:
>Was this a) a real difficult question? 

No, but it isn't trivial either.

>b) a really stupid question that
>I should find the answer to in a FAQ? c) a really silly question, because
>no one sane person would do what I'm doing? 

Well you are not in the mainstream I guess, having descended below the 
documented API.

>d) somehow while the post made
>it to the news server, it didn't make it to the mailing list, and everyone
>else is reading the list from there?

e) The experts were all busy and haven't been paying attention.

>> 
>> There are a bunch of options with my object that I need to retrieve in the
>> XS code. To this end I wrote these two routines:
>> 
>>   static SV **fetch_from_hash (SV* olle_ptr, hash_key_id id) {
>>      HV * hv;
>>      hv = (HV *) SvRV(olle_ptr);
>>      return hv_fetch(hv, hash_keys[id], strlen(hash_keys[id]), FALSE);
>>    }
>> 
>>    static SV * fetch_option(SV * olle_ptr, hash_key_id id) {
>>    // Fetches an option from the hash, and only returns an SV, if there is 
>a
>>    // defined value.
>>       SV  **svp;
>>       SV  * retsv = NULL;
>>       svp = fetch_from_hash(olle_ptr, id);
>>       if (svp != NULL) {
>>          mg_get(*svp);
>>          if (SvOK(*svp)) {
>>             retsv = *svp;
>>          }
>>       }
>>       return retsv;
>>    }

The thing is you are calling things at quite a low level where you are 
expected to know what you are doing ;-)
Not many people call mg_get() directly - only those of use that 
poke about in sources or started this before handy macros existed.

But there is a cryptic hint in perlguts.pod 

"Similarly, generic C code must call the
C<SvGETMAGIC()> macro to invoke any 'get' magic if they use an SV
obtained from external sources in functions that don't handle magic.
See L<perlapi> for a description of these functions."

      The trick is 

      SvGETMAGIC(sv) which expands to  if (SvGMAGICAL(sv)) mg_get(sv);

And if you ever set it before you return you need:

      SvSETMAGIC(sv);


>> 
>> I found that if I did not add the call to mg_get, SvOK would not return
>> TRUE. This appears to work, but now I have run into a situation where
>> the call to mg_get causes an access violation. Some pieces of the Perl 
>> code:
>>  
>>    @ISA = qw(Exporter DynaLoader Tie::StdHash);
>>    ...
>>    sub FETCH {
>>       my ($self, $key) = @_;
>>       if (not exists $myattrs{$key}) {
>>          croak("Attempt to fetch undefined OlleDB attribute '$key'");
>>       }
>>       if ($key eq "SQL_version" and not defined $self->{$key}) {
>>           # If don't have it, we must retrieve it, and save it. 
>>           my %sqlversion = $self->internal_sql(
>>                  "EXEC master.dbo.xp_msver 'ProductVersion'")
>>           $self->{SQL_version} = $sqlversion{'Character_Value'};
>> 
>> And this call to internal_sql will pass the command to SQL Server to
>> retrieve the result. Except for a minor difference this is the same
>> code path as for any other command. But this is where I get the
>> access violation in mg_get. I suppose the reason is that since I 
>> come from the FETCH method, *svp is not magic at this point. But
>> how can I tell? 

See above.

>> Or should I check *svp for a true 

Do you mean a "true" boolean value SvTRUE(sv) or defined value SvOK(sv) ?

>> value in some
>> better way than I do?

       if (svp != NULL) {
          SvGETMAGIC(*svp);
          if (SvOK(*svp)) {
          }


>> 
>> I believe that I should be to workaround this by adding some extra
>> parameter that prevents me from fetching options when coming from 
>> FETCH. I would still be interesting to learn how I am supposed to
>> deal with this situation.
>> 
>> 

Reply via email to