Hello,

I have a perl object, which is a blessed reference to a hash visible to Perl. That visible hash is tied to a hidden hash via PERL_MAGIC_ext (to keep the Perl script's grubby fingers off my precious data). I have the following problem code:

void must_not_delete_cpp_object(SV* perl_obj, bool must_not_delete) { HV* hidden_hash; IV can_delete; SV** can_delete_sv; hidden_hash = get_hidden_hash(perl_obj); can_delete_sv = hv_fetch(hidden_hash, "_can_delete", 11, 0); can_delete = must_not_delete ? 0 : 1; sv_setiv(*can_delete_sv, can_delete); hv_store(hidden_hash, "_can_delete", 11, *can_delete_sv, 0); }

There would seem to be no way for the hash value to be anything but 1 or 0, right? And normally it is indeed one of those two values. But when called from a C++ function instead of from XS, it's the address of the visible hash (for example, 403291944), which isn't even used in this function; it's used in get_hidden_hash().

If I put this warning: warn("Setting can_delete to %d in %d", can_delete, (IV)hidden_hash); right before the sv_setiv line, I get the following as it dies:

Setting can_delete to 0 in 403291976 at test.pl line 136. Can't coerce HASH to integer in subroutine entry at test.pl line 136.

If I put the same warning right after, I get the Can't coerce... line and it dies

So somehow, when my code is called from a C++ function, the line can_delete = must_not_delete ? 0 : 1 ends up with a hash address but can_delete is still typed as an integer. With the warning added, the value is correct, but the type somehow gets changed to a HASH and the sv_setiv line causes death. This happens even if the warning hasn't been emitted, so the mere presence of the warning causes a change in type.

But this only happens when called from C++; when called from XS, can_delete is an integer and is either 0 or 1, the warning is emitted, the hash element is set, and the script goes merrily on its way.

The background is, I am creating some subclasses and linking them to Perl classes. Most of the time, I want the C++ object to be deleted when the Perl object goes out of scope. But sometimes the system takes ownership of the objects, and I can't delete them.

If I already know when I create the object that the system is going to take ownership, I call the function from my XS new() function:

must_not_delete_cpp_object(RETVAL->perl_obj, true);

In other cases, the system may or may not take ownership, depending on what the Perl script does with the object; in these cases, the C++ object may be deleted by the system while the Perl object is still in scope, so I call the function from the C++ destructor:

must_not_delete_cpp_object(perl_obj, true);

I see no difference between these two calls, other than the fact that one uses an member variable from within a class and the other from without. And yet the second call gives the odd results shown above.

For reference, here's get_hidden_hash():

HV* get_hidden_hash(SV* perl_obj) { SV* underlying_hash; MAGIC* mg; HV* hidden_hash; // get the underlying hash that the perl_obj is a reference to // (we can leave it an SV* because we're just using it to find mag +ic) underlying_hash = SvRV(perl_obj); // get the hidden hash linked to the perl_obj mg = mg_find(underlying_hash, PERL_MAGIC_ext); hidden_hash = (HV*)mg->mg_obj; return hidden_hash; }

In reply to Integer seen as hash? by jalopeura

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.