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. >> >>