http://www.perlmonks.org?node_id=1034892

BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

This is a revival of a golden oldie.

I need to use stderr from an Inline::C routine, but whilst the symbol is defined, it has been redefined by Perl's header to something that is incompatible with stdio.h calls. The result is that the code compiles but segfaults when the crtlib routine is called.

The solution that I arrived at in that old thread (eprintf), is no good for my current purpose as I need to give stderr to fwrite.

I tried #undef stderr prior to #include <stdio.h>, but then get error C2065: 'stderr' : undeclared identifier

Any thoughts on how I can obtain stderr within Inline C?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
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.

Replies are listed 'Best First'.
Re: Using stderr from Inline::C: (part deux)
by syphilis (Archbishop) on May 23, 2013 at 10:20 UTC
    Using the perlio layer works fine for me:
    #!perl -w use warnings; use strict; use Inline C => Config => USING => 'ParseRegExp', BUILD_NOISY => 1; use Inline C => <<'EOC'; void foo(char * x, int y) { PerlIO_write(PerlIO_stderr(), x, y); } EOC my $str = "hello world\n"; foo($str, length($str)); foo($str, 8); __END__ Outputs: hello world hello wo
    Does that also work for you ? Is it acceptable ? (IIRC, you're not a big fan of the perlio layer.)

    Alternatively, what about the XSubs warn() and/or vwarn() - both of which write to stderr ?

    Cheers,
    Rob
      (IIRC, you're not a big fan of the perlio layer.)

      I'm not a fan of anything that imposes itself on me. Even less so when it is done by overriding standard names with text macros.

      The latter wouldn't be so bad if it was only done if I explicitly requested it. Say, by adding: #include <perlIO.h> or similar.

      It would also not be so bad if it was documented what extra these PerlIO equivalent were doing for me (as opposed to just their existence.). One assumes they must be doing something extra, otherwise there would be no benefit for the cost of all those extra indirections; but I have yet to see what that is documented.

      Talking of control, is it possible to avoid/prevent I::C from automatically adding the standard Perl/XS headers to my I::C code?

      I wondering how I might use the NO_XSLOCKS that bulk88 mentions with I::C?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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.
        I wondering how I might use the NO_XSLOCKS that bulk88 mentions with I::C?

        Should be easy enough.
        Looking at the post to which bulk88 provided a link, I see:
        >You need to add > > #define NO_XSLOCKS > >before > > #include <xsub.h>
        If that's correct, then this should provide what's needed:
        use Inline C => Config => PRE_HEAD => "#define NO_XSLOCKS\n";
        (Not sure if the '\n' is needed or not ... and haven't checked.)
        The PRE_HEAD config option is a recent addition (beginning in 0.51) - it's documented in 'perldoc Inline::C'.

        Cheers,
        Rob
Re: Using stderr from Inline::C: (part deux)
by hdb (Monsignor) on May 23, 2013 at 07:31 UTC

    This might not be of great help to you, but under Win32 strawberry-perl 5.16.3.1 #1 Tue Mar 12 12:12:07 2013 x64 the following code works:

    use strict; use Inline C => <<'__C__'; #include <stdio.h> void test ( ) { char buffer[] = { 'x' , 'y' , 'z' }; fwrite (buffer, 1, sizeof(buffer), stderr ); } __C__ test( );

    Reading your old thread, it looks to me that the root cause of the problem was a mismatch of compilers. So one solution could be to either change compilers or re-compile Perl with your preferred compiler.

      the root cause of the problem was a mismatch of compilers.

      Kinda. Sorta. But not really.

      I::C code is compiled to a runtime linked dll. There is nothing fundamentally wrong with using multiple different CRTs within different dlls in the same process. (provided you don't try to mix'n'match by (say) mallocing with one and freeing with another.)

      Indeed, this is (so far; but I've been doing it for a good many years) the only real problem I've encountered with using a different compiler for building modules and I::C stuff, than was used to build the AS perl I use.

      The problem is that the Perl headers pull in a shitload of the PerlIO crap regardless of whether the code being compiled uses it or not. And it is that PerlIO crap that is screwing this up.

      So one solution could be to either change compilers or re-compile Perl with your preferred compiler.

      Neither of those is an option. It has to be AS perl. The compiler AS use is no longer available; neither is (their) source for the build of Perl I need for this.

      But thanks for your reply.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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.
Re: Using stderr from Inline::C: (part deux) (fileno/dup2)
by Anonymous Monk on May 23, 2013 at 07:19 UTC

      Thank you anonymonk. The last post in the subthread you linked showed the use of _write) which does what fwrite() does, but takes a fileno rather than stream handle, and that works just fine. Presumably because the fileno gets used to look up the appropriate stream stuff internally, and thus gets to use the correct expansion of __iob_func().


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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.