Chapter: Multicore Application Programming For Windows, Linux, and Oracle Solaris - Windows Threading

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail

Wide String Handling in Windows

Since Windows NT 4, Windows has used Unicode as its default text encoding format. Unicode defines support for greater than 8-bit encoding of characters. Windows uses UTF-16 format, known as wide character encoding, which uses two bytes per character.

Wide String Handling in Windows

 

Before we discuss the handling of multiple processes in Windows, it is necessary to have a short discussion of the handling of strings.

 

Since Windows NT 4, Windows has used Unicode as its default text encoding format. Unicode defines support for greater than 8-bit encoding of characters. Windows uses UTF-16 format, known as wide character encoding, which uses two bytes per character. Many Windows functions are defined with two entry points: a Unicode version that has a W appended, for wide character, or an ANSI character entry point that is appended with an A. For example, the CreateMutex() function call has a supporting CreateMutexW() and a CreateMutexA(). At compile time, the appropriate function call will be made depending on whether UNICODE is defined. Since Windows uses wide characters inter-nally, the ANSI entry points are just wrappers around the wide versions of the function calls with appropriate string conversion.

 

The 16-bit character type is wchar_t. This can be used as a replacement for the char type. WCHAR is an equivalent method of specifying a wide string. However, strings of characters in source code are interpreted as being ANSI 8-bit characters, which is why they need to be specified as being wide characters. This can be performed using the L specifier or using the TEXT() macro, as demonstrated in Listing 6.24. We will need to use these macros in later examples when we specify string constants.

 

Listing 6.24   Assigning a Compile-Time Value to a Wide Character String

wchar_t mystring1[] = L"Some text";

WCHAR mystring2[] = TEXT("More text");

The TEXT() macro is useful in that when UNICODE is defined, it translates a string to wide character format. When UNICODE is not defined, it leaves the string as ANSI 8-bit text. The TCHAR type behaves in a similar way, resolving to wchar_t when UNICODE is defined, or char otherwise.

 

Some functions are defined as macros that resolve differently depending on whether UNICODE is defined. For example, the main function _tmain() resolves either to wmain() when UNICODE is defined or to main() otherwise. Similarly, _tprintf() will either resolve to wprintf() or printf().

 

Creating Processes

 

To create a new process, the first process calls CreateProcess(), which takes a number of parameters. The three critical parameters are the name (and any parameters) of the process to be run, together with a pointer to a STARTUPINFO structure and a PROCESS_ INFORMATION structure. Table 6.4 shows the full parameters to this function.

 

Table 6.4      Parameters Passed to CreateProcess()


The first parameter is the application name, and the second parameter is the com-mand line. These two parameters work together. If either is null, the other is used as the entire command line. Otherwise, the application named by the first argument is executed but passed the command line given by the second argument. This means that the first parameter of the command line should be a repeat of the name of the application.

 

There are two further considerations: The Unicode version of this function, CreateProcessW(), is called, and the command line can be modified; hence, it should always be stored in a variable rather than a constant string. Second, if the application name is null, then the application executed will be the first whitespace-delimited text in the command line. If the path to the application contains a space, then the entire path and name should be enclosed in quotes.

 

The third and fourth parameters are optional pointers to SECURITY_ATTRIBUTES. The first gives the attributes for the created process, and the second of these is attributes for the first thread of the created process. These attributes principally determine whether child processes of the created process will inherit any handles owned by the created process. A null value for these pointers provides the created process with the default attributes.

 

Both the STARTUPINFO and PROCESS_INFORMATION structures should be zero-filled before the call. The cb member of the STARTUPINFO structure needs to be set to the size of the structure. The call to CreateProcess() will record information in these struc-tures. The most important information will be the handle of the new process that is recorded in the hProcess member of the PROCESS_INFORMATION structure.

 

Listing 6.25 shows the steps necessary to create a new process. If the application is started with a command-line parameter, the process will print this out and then create a child process without any parameters. If the process is started without any parameters, it prints out a message indicating this and exits.

 

Listing 6.25   Starting a New Process

#include <Windows.h>

 

int _tmain( int argc, _TCHAR* argv[] )

 

{

 

STARTUPINFO startup_info;

 

PROCESS_INFORMATION process_info;

 

if ( argc>1 )

 

{

 

wprintf( L"Argument %s\n", argv[1] ); wprintf( L"Starting child process\n" );

 

ZeroMemory( &process_info, sizeof(process_info) ); ZeroMemory( &startup_info, sizeof(startup_info) ); startup_info.cb = sizeof(startup_info);

 

if (CreateProcess( argv[0], 0, 0, 0, 0, 0, 0, 0,

 

&startup_info, &process_info )==0 )

 

{

 

printf( "ERROR %i\n", GetLastError() );

 

}

 

WaitForSingleObject( process_info.hProcess, INFINITE );

 

}

 

else

 

{

 

printf( "No arguments\n" );

 

}

 

getchar();

 

}

 

 

The handle of the created process is returned in process_info.hProcess. This handle is used in the call to WaitForSingleObject(). This call returns when the child process exits.

 

The call to getchar() at the end of the code is there to wait for the Enter key to be pressed before the process exits.

 

To pass arguments to a child process, it is necessary to repeat the application name as the first command-line parameter. The entire command line gets passed to the child process. Listing 6.26 shows the situation where the child process is started with a single additional argument.

 

Listing 6.26   Passing Arguments to a New Process

 

#include <Windows.h>

 

int _tmain( int argc, _TCHAR* argv[] )

 

{

 

STARTUPINFO startup_info;

 

PROCESS_INFORMATION process_info;

 

if ( argc==1 )

 

{

 

printf( "No arguments given starting child process\n" );

 

wchar_t argument[256];

 

wsprintf( argument, L"\"%s\" Hello", argv[0] );

 

ZeroMemory( &process_info, sizeof(process_info) ); ZeroMemory( &startup_info, sizeof(startup_info) ); startup_info.cb = sizeof(startup_info);

 

if (CreateProcess( argv[0], argument, 0, 0, 0, 0, 0, 0, &startup_info, &process_info )==0 )

{

 

printf( "ERROR %i\n", GetLastError() );

}

 

WaitForSingleObject( process_info.hProcess, INFINITE );

 

}

 

else

 

{

 

wprintf( L"Argument %s\n", argv[1] );

 

}

 

getchar();

 

}


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.