News:

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

Console Output Handle

Started by Neil, November 27, 2008, 11:40:10 AM

Previous topic - Next topic

Neil

I have a number of procs which all begin :-

     LOCAL hOutPut:DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut,eax

Is there any advantage in making this Handle Global i.e. doing it only once at the beginning of the program & thus doing away with all the GetStdHandle handle calls.

Vortex

Yes, you can make it global to avoid multiple calls to GetStdHandle

Neil

Thanks Vortex, why I had my doubts was because I was taught that it was good practice to release a handle as soon as it was finished with.

Vortex

Hi Neil,

You are welcome.

You can have a look at the source code of StdOut.asm, it does not release the handle at the end :

StdOut proc lpszText:DWORD

    LOCAL hOutPut  :DWORD
    LOCAL bWritten :DWORD
    LOCAL sl       :DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut, eax

    invoke StrLen,lpszText
    mov sl, eax

    invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL

    mov eax, bWritten
    ret

StdOut endp

Tedd

Quote from: Neil on November 27, 2008, 11:54:44 AM
I was taught that it was good practice to release a handle as soon as it was finished with.

That's right, but you're not finished with it until you've finished printing text to the console :wink

The handle actually exists whether you use it or not - it's created when the program is loaded (which is why you have to link as a console program; or you must AllocConsole yourself to create it.) You didn't actually create it, so you're not the one destroying it either. Apply that rule to handles you specifically create, e.g. file handles, graphic objects, etc.
No snowflake in an avalanche feels responsible.

Neil

Thanks Vortex & Tedd for clearing that one up :thumbu

redskull

In keeping with the way "they" teach, the preferred method might be to get the handle once, in the beggining, and then pass it to each function that needs to print as an argument, in lieu of accessing the global varaible directly from each WriteFile() line.

-alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Mark Jones

I think the MASM32 "print" macro gets this handle every time it is used. When I would run a MASM32 console program through MemProof (a memory leak tool, search here) it would report many such "unfreed handles." However Tedd is correct, when we "GetStdHandle" it is not actually creating a handle, just giving us the handle which is already there. Thus, perhaps a few clock cycles could be saved if we get this handle once and referr to it globally.

Here is a basic routine in GoASM syntax, which outputs unicode text. If "threaded" is defined (#define threaded), it becomes thread-safe, meaning two or more threads from the same process cannot write text to the output at the same time.


.data
CSect CRITICAL_SECTION<> ; threading info

.code

coutt frame hConsole,lpTextW ; console-out (threaded)
local n ; returns nChars as eax

#ifdef threaded
invoke EnterCriticalSection,addr CSect ; only allow one at a time
#endif
xor eax,eax ; get length of text arg
mov ecx,[lpTextW]
: cmp w[ecx+eax],0
jz >
add eax,2
jmp <
: shr eax,1 ; eax = n unicode chars
invoke WriteConsole,[hConsole],[lpTextW],eax,addr n,0
#ifdef threaded
invoke LeaveCriticalSection,addr CSect
#endif
mov eax,[n]
ret
endf


Use as:


.data
align 4
hCin dd ? ; console handles
hCout dd ?
hCerr dd ?
wMyString dw "Hello World from UNICODE land!",13,10,0

.code
start:
invoke GetStdHandle,STD_INPUT_HANDLE ; get console handles (once)
mov [hCin],eax
invoke GetStdHandle,STD_ERROR_HANDLE
mov [hCerr],eax
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov [hCout],eax
invoke SetConsoleMode,[hCin],ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT

invoke coutt,[hCout],addr wMyString ; print desired text to hCout
; number of characters written returned in EAX
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08