News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

printf and std os redirection

Started by johnsa, February 02, 2012, 10:18:06 AM

Previous topic - Next topic

johnsa

Hi,

Normally from a C app, I'd use printf and if I ran the app from the console as follows:
myapp.exe param > out.txt
The printf calls would be redirected to file.

However, using msvcrt.lib/masm32 include etc from an asm program the same does not work.
normal calls to print / StdOut macro ARE being redirected, however all printf's stay on screen...

Any ideas?
Thanks
John

johnsa

I'm wondering if the C app does some CRT init that allows the printf redirection to work?

hutch--

Jpohn,

If you have MASM32 version 11, just use the "printf" macro, it works very close to the C original. Michael Webster wrote the original macro and it has had a UNICODE version added as well. Both call functions from MSVCRT.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

qWord

is the subsystem = CONSOLE or did you use AllocConsole()?  - allocated consoles requires to set CRT's I/O handles.
FPU in a trice: SmplMath
It's that simple!

bozo

Quote from: johnsa on February 02, 2012, 10:50:57 AM
I'm wondering if the C app does some CRT init that allows the printf redirection to work?

Can't check right now but that's probably the issue.

johnsa

subsystem = console.

I really think it's something to do with CRt startup..

If the printf macro also calls msvcrt it's going to have the same problem?

dedndave


qWord

FPU in a trice: SmplMath
It's that simple!

hutch--

John,

Try this with MASM32 version 11.



; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    __UNICODE__ equ 1

    include \masm32\include\masm32rt.inc

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤


    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    printf("this is the MASM32 default version of \qprintf\q\n\n");

    printf("It handles numbers using the normal C escapes\n\n");

    printf("%X or %x or %u or %d\n\n",1234,1234,1234,-1234);

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start


This is the output to the console.



this is the MASM32 default version of "printf"

It handles numbers using the normal C escapes

4D2 or 4d2 or 1234 or -1234

Press any key to continue ...
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

...if Hutch's example doesn't work...
i found some code by qWord that uses setvbuf for piping...
http://www.masm32.com/board/index.php?topic=15984.msg132047#msg132047

Tedd

Just a guess (unable to check right now)...

If printf is using WriteConsole, then redirection will fail.
Using WriteFile with GetStdHandle(STD_OUTPUT_HANDLE) as the file-handle does work correctly (output goes to the console by default, or to a file if redirected to one, etc.)
No snowflake in an avalanche feels responsible.

dedndave

out of curiosity, i made a small app using printf
it redirects with no problems
maybe it's the specific format you are using - or, perhaps, the environment

are you running in a virtual environment or something ?

MichaelW

This KB article shows a way to do it programmatically in C/C++:

http://support.microsoft.com/kb/58667

But I could not find a way to do it from a MASM app until I found this:

http://www.masm32.com/board/index.php?topic=17326.msg145357#msg145357


;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================

_iobuf STRUCT
    _ptr        DWORD ?
    _cnt        DWORD ?
    _base       DWORD ?
    _flag       DWORD ?
    _file       DWORD ?
    _charbuf    DWORD ?
    _bufsiz     DWORD ?
    _tmpfname   DWORD ?
_iobuf ENDS
FILE TYPEDEF _iobuf

stdout MACRO
    call crt___p__iob
    add eax, SIZEOF FILE
    EXITM <eax>
ENDM

;==============================================================================
.data
.code
;==============================================================================
start:

    printf("before redirect\n");

    invoke crt_freopen, chr$("file.txt"), chr$("w"), stdout()

    printf("after redirect\n");

    invoke crt_freopen, chr$("CON"), chr$("w"), stdout()

    printf("after re-redirect\n");

    inkey
    exit
;==============================================================================
end start

eschew obfuscation

dedndave

#13
stdout  MACRO
        call    crt___p__iob
        add     eax, SIZEOF FILE
        EXITM   <eax>
ENDM


that's the part i could not figure out from the documentation
mainly because the C compiler does it for you - little need to document what goes on under the hood   :P

what i don't get with that code is that you are using a "printf" macro from someplace
in Erol's code, he uses fprintf

i am gonna steal your stdout macro   :bg
i'd be interested to know if this code works under windows 7
i am guessing the problem is due to the fact that, under win 7, the console is run in a virtualized environment

EDIT: corrected the code - see post #15

MichaelW

Quote from: dedndave on February 03, 2012, 04:30:09 AM
stdout  MACRO
        call    crt___p__iob
        add     eax, SIZEOF FILE
        EXITM   <eax>
ENDM


that's the part i could not figure out from the documentation
mainly because the C compiler does it for you - little need to document what goes on under the hood   :P

what i don't get with that code is that you are using a "printf" macro from someplace
in Erol's code, he uses fprintf

I'm using the printf macro from MASM32 v11r.

I should have included some additional information that I got from the Microsoft header files when I was trying to figure out how I could get the address of the CRT's iob (i/o buffer) array.

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

/* Declare _iob[] array */
#ifndef _STDIO_DEFINED
_CRTIMP extern FILE _iob[];
#endif  /* _STDIO_DEFINED */

#define stdin  (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
eschew obfuscation