digitalmars.com                        
Last update Mon Mar 8 17:52:42 2010
Compiler & Tools Guide

Tools
BCC
CHMOD
CL
COFF2OMF
COFFIMPLIB
DMC
DIFF
DIFFDIR
DUMP
DUMPOBJ
DUMPEXE
EXE2BIN
FLPYIMG
GREP
HC
IMPLIB
LIB
LIBUNRES
MAKE
MAKEDEP
ME
OBJ2ASM
PATCHOBJ
RC
RCC
SC
SHELL
SMAKE
TOUCH
UNMANGLE
WHEREIS


Compiling
Compiling Code
C Implementation
C++ Implementation
Language Extensions
Mixing Languages
Assembly Language
Inline Assembler
Optimizing Code
Numerics Programming
Regular Expressions
Acrtused
Pragmas
Precompiled Headers
Predefined Macros
Warning Messages
Error Messages
Runtime Messages


Linking
Optlink
Switches
Module Definition Files
Operation and Design
Error Messages


Win32 Programming
Win32 Programming


DOS and Win16
Programming

Memory Models
16 Bit Pointer Types
and Type Modifiers

Handle Pointers
DOS
DOS 32 (DOSX)
Win16
Win16 DLLs
Win16 Prolog/Epilog
Virtual Memory
For 640Kb DOS



C/C++ Extensions
Contract Programming
__debug statement
__debug declaration
Dynamic Profiling
Embedding C in HTML


Porting to DMC++
Switching to DMC++
from Microsoft
from Borland
Porting Guide



Win32 Programming Guidelines

This chapter describes how to use the compiler to create Win32 and Win32s applications. For information about:

What's in This Chapter

  • How creating 32-bit Windows applications differs from creating 16-bit Windows applications.
  • The distinctions between 32-and 16-bit graphical environments and Digital Mars' support for Win32, Win32s and development tools.
  • How to compile and link various Win32 applications, including applications that use MFC.
  • How to compile and link Win32s applications.
  • How to recompile and relink 16-bit applications to be 32-bit Windows applications.

Some Basic Information

The following will help you understand the information in this chapter.
  • Windows 3.1 is a 16-bit graphical environment that runs on DOS, which is a 16-bit operating system. For simplicity, Windows 3.1 (and 3.0) will be referred to as Win16.
  • Windows 95 and Windows NT (Windows New Technology) are 32-bit operating systems. For simplicity, Windows 95 and Windows NT will be referred to as Win32.
  • Win32s is an NT emulator, or operating system extension, that allows you to run Win32 applications on a Win16 host.
  • 32-bit applications for Windows are referred to as Win32 applications. 16-bit applications for Windows are referred to as Win16 applications.
  • The Win32 Applications Programming Interface (API), the graphical environment for Windows 95 and NT, is very similar to the Windows 3 graphical environment.
For machines based on the Intel 80x86 architecture, a 32-bit operating system improves the performance of data manipulation and calculations because it avoids the overhead of loading segment registers. Applications that are data-, memory-, or calculation-intensive may perform significantly better in 32-bit mode.

About Win32s

Win32s is an NT emulator or operating system extension that allows you to run Win32 applications on a Windows 3.1 host. The "s" in Win32s stands for Win32 subset: Win32s supports almost all Win32 API features.

Note: Win32s applications built with C++ Version 7 will only run on version 1.15 and above of Win32s.

Advantages of Win32s over Win16

Win32s, included with Digital Mars C++, gives you the following advantages over conventional Win16 applications:
  • The ability to run 32-bit programs under Windows 3.1.
  • The ability to manipulate data and perform calculations in 32-bit mode, which improves the performance of applications that are data-, memory-or calculation intensive, such as spreadsheets, simulation packages, desktop publishing and CAD packages.
  • Features previously unavailable in Windows 3.1, such as sparse memory.
Win32s lets your Win32 applications make 32-bit calls to Windows 3.1, where graphics and windowing operations are performed. Win32s consists of a virtual device driver (VxD) and a set of dynamic link libraries (DLLs) that extend Windows to support 32-bit applications.

Key Win32s features

Many features are available through the Win32s Applications Programming Interface (API), such as:
  • Complete window interface
  • All graphics functions (GDI)
  • Object linking and embedding (OLE), version 1.0
  • Memory-mapped files (backed by disk image)
  • Network support, such as Netbios and named pipes
  • Common dialogs
  • Named shared memory

Building Win32 and Win32s Applications

Digital Mars C++ includes a set of tools that make it easy to create and debug Win32 and Win32s applications from either the command line or within the integrated environment. By setting switches, all the tools— compiler, linker, resource compiler, and resource editors— generate the correct type of 32-bit application. The following is basic information useful for building Win32 and Win32s applications:
  • The compiler generates Microsoft OMF object files. OPTLINK does not use Microsoft COFF files.
  • In order to compile with the correct startup code, Win32 and Win32s executables need to contain a WinMain() entry point. This causes the compiler to generate a reference to the _acrtused startup function.
  • Use a module definition file to define explicitly as many criteria as possible. To establish the proper executable for NT, for example, place EXETYPE NT in your module definition file, and use the SUBSYSTEM[ WINDOWS] keyword. For further information on Win32 .def files, see Definition File Directives.
  • The -mn switch is the memory model switch for Win32 applications available from the command line interface. This is the 32-bit flat model, essentially a "small model" with 4GB addressing.
  • Creating a resource file for a Win32 application is no different from creating one for a Win16 application. The resource compiler takes a resource definition file and produces a 32-bit .res file. Having 16-bit compatibility with the .res files helps you build Win32 applications from Win16 applications.
  • When creating Win32 applications, OPTLINK provides transparent linking and binding of .res files to an .exe file. 16-bit .res files are converted to 32-bit during the link process.
The OPTLINK linker does not support COFF format .lib or .obj files produced by Microsoft tools.

Note: To developers using NT: OPTLINK (the linker) does not accept COFF resource files, but does accept standard Microsoft resources files.

Compiling Win32 Executables

This section explains how to create various kinds of Win32 executables.

Compiling with MFC 3.x

If your Win32 application uses MFC 3.x libraries, see the "READ ME" file included with the distribution for a list of the options, libraries, and #defines you need to build various targets with the latest MFC release. Note that, for all MFC 3.x libraries, you need to compile with the NT (-mn) memory model.

Compiling Win32 DLLs

To compile Win32 DLLs, use these compiler options:
-mn -WD 
To write a Win32 DLL, you need to specify the entry point DllMain(). When the compiler detects a call to DllMain() in a 32-bit compilation, it generates a reference to the _acrtused_ dll startup function, and links with the appropriate startup code.

Unlike previous versions of C++, this startup code calls static constructors and performs other initialization steps before calling DllMain().

Converting older Win32 DLLs

To convert Win32 DLLs built with previous versions of C++ to work with this version, make the changes listed below:
  • Remove any references to #pragma startaddress.
  • Provide a reference to DllMain().
  • If the entry point routine was not DllMain(), write a new DllMain() stub that calls the entry point routine upon process_attach().
  • If you need to write code that is called prior to static construction, check the source for the run-time library to determine what calls are necessary to initialize the library. Then use #pragma startaddress to specify the entry point, and call the initialization routines as needed.
Note: Win32 DLLs compiled with previous versions of C++, in which the entry point is specified with #pragma startaddress, need to be rewritten to call DllMain() instead. Otherwise any static constructors will not be called, and any run-time library calls will not work as expected because proper initialization has not taken place.

Building Console Applications

A console application is a character mode application that runs under Windows 95 or NT. Digital Mars C++ supports console mode applications.

To compile console applications, use the -mn compiler option, and specify the SUBSYSTEM CONSOLE directive in the .def file.

Startup code for console applications

When the compiler detects a call to main() in a 32-bit compilation, it generates a reference to the _acrtused_ con startup function, and links with the appropriate startup code. You no longer need to explicitly link in cc.obj, as with previous versions of C++; it is now part of snn.lib.

Compiling Win32s Executables

To compile Win32s executables, use the -mn and -WA compiler options. Note: HP Dashboard does not support Win32s. If you try to debug a Win32s application under Dashboard, the debugger receives a GPF message from the application being debugged.

Compiling Win32s DLLs

To compile Win32s executables, use the -mn and -WA compiler options.

Note: To create libraries from Windows NT System DLLs (kernel32.dll, for example), use the IMPLIB utility and specify the /system switch. IMPLIB is available only from the command line, not via the IDDE.

Win32 Definition File Directives

This section lists the directives used in definition files for Win32 programs. For descriptions of these directives see Definition File Directives.
NAME name [BASE=number] 

LIBRARY name [ BASE= number | PROCESSINIT |
	PROCESSTERM | THREADINIT | 
	THREADTERM ] 

DESCRIPTION 'descriptive line' 

EXETYPE NT 

HEAPSIZE [number, commit] 

STACKSIZE [number, commit] 

STUB 'filespec' 

SUBSYSTEM [ NATIVE | WINDOWS | CONSOLE | POSIX ] 

VERSION number[. number] 

CODE [READ] [WRITE] [EXECUTE ] [SHARED] 

DATA [READ] [WRITE] [EXECUTE] [SHARED] 

SEGMENTS
{   name [CLASS 'class'] 
	[READ] [WRITE] 
	[EXECUTE] [SHARED]
} 


IMPORTS { [internal=] externalfile. func } 

EXPORTS { parms [=intname] [@number [NONAME]] 
	[CONSTANT]} 

Recompiling Win16 Applications for Win32

To convert to a Win32 or Win32s application to a Win16 application created with the C/C++ compilers, try these suggestions:
  • In order for Win32 to interpret handles properly, declare all handles as HANDLE, HINSTANCE, or similarly. Win32 will not properly interpret handles that use int or WORD. The sample program ZOOM illustrates how to declare handles correctly.
  • When you compile with the -mn or -mf memory models, the following keywords are ignored: __far, __huge, __interrupt, __loadds, and __handle.
  • In all Windows NT code, SS==DS==ES at all times; otherwise the NT API functions themselves can fail. When using the -mn or -mf memory models, SS==DS==ES automatically for all functions, including run-time library functions.
  • Some Win16 API functions are not supported by Win32. For example, replace calls to MoveTo() with MoveToEx() calls.
  • Replace all machine-specific code with non-machine specific C or C++ functions to make your code as portable as possible. For example, Use time() and localtime() instead of calling int86().
  • For message passing and other functions that use wParam, declare parameters with WPARAM type. This is especially true for message passing between windows, such as with SendMessage(). Using the WPARAM type allows the parameter to be interpreted as a 16-bit value for Win16 and 32-bit value for Win32. Functions declared as lParam are dwords in both implementations.
  • Win32s executables that call 16-bit DLLs need to use the Universal Thunk mechanism to communicate.
  • For mixed model programs, perform these steps:
    1. Select the Large memory model.
    2. Rebuild the project as a Win16 application.
    3. If the project builds and runs correctly, convert it to Win32, but first make any of the adjustments previously mentioned.
Note: For more tips on how to solve specific problems that might occur when porting 16-bit code to Win32, see Porting Guide.

Converting Non-Digital Mars Win16 Applications to Win32 Applications

The following information will help you convert 16-bit programs developed with other programming tools to be Win32 or Win32s applications.

Start with a bug-free Win16 application. Be sure your Win16 application compiles and runs without any compiler or linker errors or warnings.

Convert the application to be a Win16 application. For instructions on porting code from Borland or Microsoft, see Switching to Digital Mars C++. Be sure the converted program compiles and runs with Digital Mars C++ without any errors or warnings.

Save the original source code and makefile, preferably in another project directory. Now that the application is a Digital Mars Win16 application, convert it to Win32, following the hints above.

Finally, after a clean build, preferably with no warnings, test the application.

If you are targeting both Win32 and Win32s, you should test these applications thoroughly in both environments, as there are a number of significant differences between Win32 and Win32s.