Solved

Using AllocConsole

Posted on 2001-06-14
8
1,585 Views
Last Modified: 2012-06-21
Hi,i use AllocConsole inside my com exe serever,then try to write with printf to console - and it works fine,than im calling some dll's function,which also uses printf, but i'v got nothing in the console window.
What can be the problem?
0
Comment
Question by:roman_mil
8 Comments
 
LVL 3

Expert Comment

by:gmleeman
Comment Utility
I dont think DLLs can easily use printf unless you redirect the stdout stream to the specific console window that you opened with another thread.
Did you create the DLLs?
0
 

Expert Comment

by:NickAtBOM
Comment Utility
COM servers shouldn't really use printf or cout as they should be designed to run without any interaction from a user.  Can you use TRACE for debugging then write to a log at run time?
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>im calling some dll's function,which also uses printf

The problem is that each DLL usually uses it's own copy of the CRT, thus making it impossible for functions in your COM DLL to use the same instance of 'stdout'. Why do you need tht output? In case you need it for debugging purposes, I strpongly suggest using 'OutputDebugString()', which can be 'wrapped' to use 'printf()' functionality, e.g.

#define LOG_REPORT_BUFSIZE      2048    //  way too big, but as anything
                                        //  may be passed in...

void    __cdecl DbgPrintf       (   char*   __pszFormat,    ...)
{
    static  char    s_acOutput      [   LOG_REPORT_BUFSIZE  +   MAX_PATH];
    static  char    s_acBuf         [   LOG_REPORT_BUFSIZE];

    va_list         args;

    va_start    (   args,   __pszFormat);

    wvsprintf   (   s_acBuf,    __pszFormat,    args);

    wsprintf    (   s_acOutput,
                    "%s%s",
                    s_acBuf,
                    strchr  (   s_acBuf,    '\n')   ?   "\0"    :   "\r\n"
                );

    OutputDebugString   (   s_acOutput);

    va_end  (   args);
}

and use it like

for ( int i = 0; i < 10; i++)
      DbgPrintf ( "Counting %d", i);

To view that output, you can use a tool like 'DebugViev' (http://www.sysinternals.com/ntw2k/freeware/debugview.shtml)
0
 
LVL 2

Expert Comment

by:GloriousRain
Comment Utility
FYI,
<MSDN>
INFO: Calling CRT Output Routines from a GUI Application

Q105305


--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Win32 Application Programming Interface (API), used with:
The Microsoft Windows NT operating system, versions 3.1, 3.5, 3.51, 4.0
Microsoft Windows 95
The Microsoft Windows 2000 operating system

--------------------------------------------------------------------------------


SUMMARY
To use C Run-time output routines, such as printf(), from a GUI application, it is necessary to create a console. The Win32 application programming interface (API) AllocConsole() creates the console. The CRT routine setvbuf() removes buffering so that output is visible immediately.

This method works if the GUI application is run from the command line or from File Manager. However, this method does not work if the application is started from the Program Manager or via the "start" command. The following code shows how to work around this problem:


   int hCrt;
   FILE *hf;

   AllocConsole();
   hCrt = _open_osfhandle(
             (long) GetStdHandle(STD_OUTPUT_HANDLE),
             _O_TEXT
          );
   hf = _fdopen( hCrt, "w" );
   *stdout = *hf;
   i = setvbuf( stdout, NULL, _IONBF, 0 );
This code opens up a new low-level CRT handle to the correct console output handle, associates a new stream with that low-level handle, and replaces stdout with that new stream. This process takes care of functions that use stdout, such as printf(), puts(), and so forth. Use the same procedure for stdin and stderr.

Note that this code does not correct problems with handles 0, 1, and 2. In fact, due to other complications, it is not possible to correct this, and therefore it is necessary to use stream I/O instead of low-level I/O.



MORE INFORMATION
When a GUI application is started with the "start" command, the three standard OS handles STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all "zeroed out" by the console initialization routines. These three handles are replaced by valid values when the GUI application calls AllocConsole(). Therefore, once this is done, calling GetStdHandle() will always return valid handle values. The problem is that the CRT has already completed initialization before your application gets a chance to call AllocConsole(); the three low I/O handles 0, 1, and 2 have already been set up to use the original zeroed out OS handles, so all CRT I/O is sent to invalid OS handles and CRT output does not appear in the console. Use the workaround described above to eliminate this problem.

In the case of starting the GUI application from the command line without the "start" command, the standard OS handles are NOT correctly zeroed out, but are incorrectly inherited from CMD.EXE. When the application's CRT initializes, the three low I/O handles 0, 1, and 2 are initialized to use the three handle numbers that the application inherits from CMD.EXE. When the application calls AllocConsole(), the console initialization routines attempt to replace what the console initialization believes to be invalid standard OS handle values with valid handle values from the new console. By coincidence, because the console initialization routines tend to give out the same three values for the standard OS handles, the console initilization will replace the standard OS handle values with the same values that were there before--the ones inherited from CMD.EXE. Therefore, CRT I/O works in this case.

It is important to realize that the ability to use CRT routines from a GUI application run from the command line was not by design so this may not work in future versions of Windows NT or Windows. In a future version, you may need the workaround not just for applications started on the command line with "start <application name>", but also for applications started on the command line with "application name".
<MSDN>
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:roman_mil
Comment Utility
I need the staff not for debugging , but for log in run-time.Maybee you can suggest better solution for looging?
(not file).
0
 

Author Comment

by:roman_mil
Comment Utility
I need the staff not for debugging , but for log in run-time.Maybee you can suggest better solution for looging?
(not file).
0
 

Author Comment

by:roman_mil
Comment Utility
I need the staff not for debugging , but for log in run-time.Maybee you can suggest better solution for looging?
(not file).
0
 
LVL 86

Accepted Solution

by:
jkr earned 200 total points
Comment Utility
>>solution for looging?

That's mainly the same. If you want to diplay logging information, use the function I suggested along with the display tool I proposed.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now