Perl version Active State Perl, Build 809.

I'm working with a module that will permit programmers to connect to SQL
Server through SQLOLEDB. Part is Perl, part is XS. There is an object
representing a connection, and this is a tied hash. I have fought several
battles with this thing called magic, and my main weapon have been to guess
and to what appears to work.

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;
   }

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? Or should I check *svp for a true value in some
better way than I do?

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.


-- 
Erland Sommarskog, Stockholm, [EMAIL PROTECTED]

Reply via email to