in reply to Re^3: Inline C: using stderr segfaults?
in thread Inline C: using stderr segfaults?

Well, yes, there is a better way!...You have to start your XS files defining the macro ... #define PERL_NO_GET_CONTEXT 1

Interesting. Tracking this through, which is no easy task, this is the path taken:

  1. I use stderr
  2. which as we saw, gets translated into
    (*Perl_IStdIO_ptr(((PerlInterpreter *)Perl_get_context()))) ->pStderr((*Perl_IStdIO_ptr((( PerlInterpreter* ) Perl_get_context())) +))
  3. Perl_get_context() translates into
    Perl_get_context(void) { DWORD err = GetLastError(); void *result = TlsGetValue(PL_thr_key); SetLastError(err); return result; }

    Which looks up a thread-specific dispatch table base address, indexes into it to find the function (at offset pStderr) that returns the address of the stderr FILE* struct, and then invokes it (passing the address of the dispatch table as it's only argument).

  4. The function looked up is
    FILE* PerlStdIOStderr(struct IPerlStdIO* piPerl) { return win32_stderr(); }

    Note that the second call to Perl_get_context() is wasted anyway because it is not used.

  5. So then we call the platform specific function to return the required FILE * and we find:
    DllExport FILE * win32_stderr(void) { return (stderr); }
  6. And that, after preprocessing ends up as
    win32_stderr(void){ return ((&_iob[2])); }

So, all of that to get the address of the third entry of the global IO block table.

Now the questions you have to ask yourself are:

Like I say, there has to be a better way.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."