ZORTECH C++ FOR WINDOWS NT
==========================
Copyright (c) 1992 Symantec Corporation. All rights reserved.
January 15, 1993

INTRODUCTION
=============
This document describes how to compile Windows NT programs with 
Zortech C++. You don't need to rewrite any programs you wrote for
the Mircosoft compiler that comes with Windows NT. You just need to 
compile with ZTC, the Zortech compiler. 

COFF vs OMF 
-----------
Zortech's compilers and Microsoft's compilers use different object 
code formats. As long as you use Zortech libraries with the Zortech 
compilers and Microsoft libraries with the Microsoft compiler, 
you'll have no problem. Zortech's compilers produce OMF object code, 
while the Microsoft compiler produces COFF object code. Also, all 
the libraries that come with Zortech C++ are in OMF format, and  all 
the libraries that come with the Microsoft compiler are in COFF 
format. 

However, if you want to link together object code produced from the 
different compilers, you'll have to use Microsoft LINK. LINK can 
automatically convert OMF files to COFF files, while Zortech's BLINK 
cannot.

The Zortech tools OBJTOASM and DUPMOBJ work with both COFF and OMF 
object files. The other tools work only with OMF files. 

Other Notes
-----------
Here are some other notes to keep in mind as you use Zortech C++ for 
Windows NT:

* You cannot mix 16-bit and 32-bit code under Windows NT. Link 
  together object files that are all 16-bit code or all 32-bit code. 

* Code compiled with the Windows NT memory model (-mn) is not 
  compatible with code compiled with the OS/2 memory model (-mf) or 
  the DOSX memory model (-mx). Do not try to link together object  
  files compiled with different memory models

* The Zortech compilers do not support NT-sytle exception handling.

* In the Zortech compilers, wchar_t string constants do not support 
  unicode. 

CREATING WINDOWS NT APPLICATIONS
================================
With Zortech C++, you write and link Windows NT applications
the same way you do with the tools that came with your Windows 
NT package. The only difference is in how you compile the program.

If you're using Zortech BLINK...
--------------------------------
1) Compile your program with Zortech C++. Use the ZTC program with 
   the switches -mn -Di386. For example, to compile a file named 
   nt.c, use this line:

       ztc -mn -Di386=1 nt.c        

   This is what the switches do:

    -mn       Use the Windows NT memory model.
    -Di386=1  Define the macro i386 to let the compiler know that 
              you're compiling code to run an i386 CPU or greater.

If you're using Microsoft LINK...
---------------------------------
1) Compile your program with Zortech C++. Use the ZTC program with 
   the switches -c -mn -Di386. For example, to compile a file named nt.c, 
   use this line:

       ztc -c -mn -Di386=1 nt.c        

   This is what the switches do:

    -c        Compile only. Do not link.
    -mn       Use the Windows NT memory model.
    -Di386=1  Define the macro i386 to let the compiler know that you're
              compiling code to run an i386 CPU or greater.

2) Link your object files with Mircrosoft LINK. Be sure to specify the output 
   file and the subsystem. For example, to link the file nt.obj, use this 
   line:

       link -out:nt.exe nt.obj -subsystem:console c:\mstools\lib\*.lib


CREATING A WINDOWS NT DYNAMICALLY LINKED LIBRARY
================================================
You can compile dynamically linked library (DLL) with Zortech C++. 

Writing a DLL
-------------
You write a DLL function the same way as any other function. You do 
not have to declare it specially. For example, this is util.c, a 
file that defines a simple DLL:

  int add2(int a)
  {
      return( a+2 );
  }

Compiling a DLL
---------------
To compile a DLL with ZTC, follow these steps:

  1. Write a definition file for you DLL. Be sure to include LIBRARY, BASE, 
     EXETYPE, SUBSYSTEM and EXPORTS statments. Note that in the EXPORTS 
     statement, the internal name of the function is the public name with an  
     underscore in front. For example, this is the definition file for the DLL 
     above: 

       LIBRARY    UTIL
       BASE =     0x1c000000
       EXETYPE    NT
       SUBSYSTEM  CONSOLE
       EXPORTS    add2=_add2

  2. Compile the source file with the flags -c (compile only),  
     -mn (Windows NT memory model) to create an object file. You 
     must link separately. For example, to compile util.c above, 
     enter:

       ztc -c -mn util.c

  3. Create an import library with ZIMPLIB. For example, this 
     creates the import library util.lib:

       zimplib util.dll

Using a DLL in a Program
------------------------
When you use a DLL with a program, keep these points in mind:

  1. Make sure you declare the DLL functions in every file that uses 
     them. 

  2. Create a .def file that lists all the functions to be imported 
     from the DLL in an IMPORTS statement.

For example, this is test.c, a simple program that uses the util 
DLL: 

  #include <stdio.h>
  int add2(int a);

  void main(void)
  {
    int a, result;

    printf( "Enter a number: ");
    scanf( "%d", &a);
    result = add2(a);
    printf( "%d plus two is %d.\n", a, result );
  }

This is the ZTC command that compiles test.c:

  ztc -mn -c test.c			

And this is the BLINK command that links it:

  blink test,test,,.\util+znn,test   	

USING THE WINDOWS NT DEBUGGER
=============================
To debug your program with the debugger that came with your Windows
NT package, compile your program with the -g switch, and link it with 
Microsoft Link. You run the debugger like you do for any other program.  
For example, to compile the file dbg.c for the debugger, use this line:

    ztc -c -mn -Di386 -g dbg.c					           
					
Then link the file with this command:

    link -debug:full -debugtype:both -out:dbg.exe dbg.obj -subsystem:console
	c:\mstools\lib\*.lib

MULTITHREADED LIBRARIES
=======================
Zortech C++ supports multithreaded libraries under OS/2. To start a 
thread, call _beginthread(). To end a thread, call _endthread(). We 
recommend that you use these functions to fire off threads, rather 
than CREATETHREAD(), as these functions handle the synchronization 
necessary for the runtime libraries.

To build a multithreaded program, no special libraries are needed. 
Since most Windows NT programs are multithreaded, all the basic 
libraries are multithreaded. The multithreading support is enabled 
in the .h files by the macro:

    #define _MT    1

If you are building multithreading programs, you should define _MT 
to 1. Note that _WIN32 is also defined, since other operating systems 
support multithreaded libraries.

Multithreading is supported in all the Windows NT memory models: small, 
medium, compact, large, and NT (s,m,c,l,n).

So, to build a multithreaded program with ZTC, use the switches  
-D_WIN32 -D_MT.

Some performance degradation is impossible to avoid with multi-
threading the libraries. In particular, malloc/free and fputc/fgetc 
may be slower. If you do not intend to do storage allocation in any 
thread other than the primary thread, or the same as for stdio, you 
can get rid of the performance penalty by recompiling alloc.asm and 
fputc.asm without defining _MT, and then link them in explicitly.
Libraries can be created that can be linked both to multithreaded 
Windows NT and to DOS programs without recompiling. Compile them with
_MT. The OLDSTR?.LIB libraries are built this way. 

For examples on how to do multithread synchronization, see putenv.c, 
getenv.asm, fclose.c, fputc.asm and alloc.asm. Most other library 
functions are reentrant so they did not need synchronization. 
(sprintf is fully reentrant!)

32-BIT APPLICATIONS
===================
Widnows NT 32-bit applications must use the Windows NT memory model. 
In ZTC, use the switches -mn, -DWIN32, and Di386=1. This object model is 
incompatible at the object level with the DOSX or Phar Lap extenders (-mx and 
-mp). This means that the same binary library cannot be used with both 32-bit
DOS extender and 32-bit Windows NT programs.


BLINK
=====
These are the BLINK command-line switches you can use when linking 
programs for Windows NT. The switches you can use when linking 
programs for DOS are described in the chapter "BLINK: The Zortech 
Linker" in the manual "Compiler and Tools Reference."

Switch	           Description
---------------------------------------------------------------------
/a[lignment]:nn    Alignment. Set the .exe file alignment to 
                   nn. This switch affects the alignment for all 
                   things put into the .exe file.
/base:nn           Base. Set the base address of the image. It's
                   the same as using the BASE keyword in a
                   a .def file.
/ch[ecksum]	   Checksum. Generate an .exe checksum.
/co[deview]	   CodeView. Link for the CodeView debugger. 
/cr[ossref]	   Cross Reference File. Write a cross reference 
                   file in mapfile.CRF
/do[sseg]	   DOS Segments. Special segment ordering used by 
                   Microsoft high-level languages.
/f[arcalltranslation]	
                   Far Call Translation. Convert intrasegment far 
                   calls to near calls, used with /packcode
/fixed		   Specify that the image be fixed in place
/helpnt            Help for Windows NT. Prints an explanation for 
                   each BLINK switch you can use under Windows NT.
/inc[lude]:symbol  Add a reference to symbol as if it were used in 
                   the program. This forces the linker to bring in 
                   the module symbol is in, even if symbol isn't  
                   used in the program. 
/inf[ormation]	   Information. Print information as linker executes 
                   including the names, order, and location of the 
                   object files being linked.
/li[nenumbers]     Line Numbers. Include line numbers and associated 
                   addresses in .map file.
/machine:i386      Specify the destination machine type. BLINK 
                   accepts only i386.
/man[gle]          Mangle Names. Show mangled names instead of trans-
                   lating them into readable names.
/m[ap]	           Map. Write a full map file.
/mo[reinformation] More Information. Print more information as linker 
                   executes.
/nod[efaultlibrary]	
                   No Default Library. Ignore libraries specified in 
                   .obj files.
/nof[arcalltranslation]	
                   No Far Code Translation. Do not convert far calls 
                   to near calls. Turns off /farcalltranslation.
/noi[gnorecase]	   No Ignore Case. Become case sensitive.
/non[ulldosseg]	   No Null DOS Segment. Do not offset first segment 
                   by 0x10.
/nop[ackcode]      No Pack Code. Do not combine code segments. Turns 
                   off /packcode.
/nopackd[ata]	   No Pack Data. Do not combine data segments. Turns 
                   off /packdata.
/packc[ode]:nn     Pack Code. Combine code segments into new segments 
                   with a maximum size nn.
/packd[ata]:nn     Pack Data. Combine data segments into new segments 
                   with a maximum size nn.
/pm[type]:type     Operating System. Specify which windowing system 
                   the executable uses for Windows and OS/1. type can 
                   be PM, VIO, NOVIO, WINDOWAPI, WINDOWCOMPAT, 
                   NOTWINDOWCOMPAT. 
/st[ack]:nn        Stack Size. Set stack size of the .exe file to nn. 
                   Do not use this switch if you are linking with the 
                   Zortech compiler libraries.
/stub:file         Use file as the stub executable.
/v[ersion]:nn[.mm] Put the specified version number in the .exe file.


BLINK DEFINITION FILE SYNTAX
============================

This section describes the statements that BLINK lets you use in a 
definition (.def) file.

This section uses the following notation to describe the syntax for 
the statements:

KEYWORD         Words you must enter exactly as shown are in plain
                text.  
name            Words you must replace with a word or number of 
                your own are in italics.
[ optional ]    Optional items are in brackets.
{ repeated }    Items you can repeat one or more times are in 
                braces. 
a | b | c       Items you must choose among have vertical bars 
                between them. In this example, you can choose 
                a, b, or c.

Declaring an application
------------------------
NAME name [BASE=number]

Declare that the executable is an application, and not a DLL. A 
definition file can contain either a NAME or LIBRARY statement but 
not both. Name is the name of the internal name of the application. 
The internal name doesn't need to be the same as the external file 
name of the application.

BASE specifies the starting address of the image in virtual memory. 
If you don't include this number, BLINK uses 0x10000 as the starting 
address.

Declaring a dynamically-linked library
--------------------------------------
LIBRARY name { BASE=number | 
               PROCESSINIT | PROCESSTERM | 
               THREADINIT  | THREADTERM  }

Declare that the executable is a dynamically linked library (or DLL) 
and not an application. A DEF file can contain either a NAME or 
LIBRARY statement but not both. Name is the internal name of the 
library. It is a good idea to use the same name as both the internal 
name and the external file name.

BASE specifies the starting address of the image in virtual memory. 
If you don't include this number, BLINK uses 0x10000 as the starting 
address.

These keywords control how the DLL is intialized and terminated. 
DLLs linked with BLINK use the routine dllinit() both to terminate 
and initialize.

PROCESSINIT     Initialize the DLL once when it's loaded, no matter 
                how many applications use it. If you don't specify 
                either PROCESSTERM or THREADTERM, it also terminates
                the DLL once when it's unloaded, and all
                applications have finished using it. 
THREADINIT      Initialize the DLL each time a different application 
                uses it. If you don't specify either PROCESSTERM or 
                THREADTERM, it also terminates the DLL each time 
                an application that uses it has finished with it.
PROCESSTERM     Terminate the DLL once when it's unloaded, and all 
                applications have finished using it. 
THREADTERM      Terminate the DLL each time an application that uses 
                it has finished with it. 


Including a description
-----------------------
DESCRIPTION 'descriptive line' 

Optional. Put the string 'descriptive line' into the output file as 
a description. This statement does not effect how the executable 
file runs.

Specifying the operating system
-------------------------------
EXETYPE NT

Specify that the executable is for the Windows NT operating system.

Setting the heap size
---------------------
HEAPSIZE number[,number]

Optional. Set the size of the heap.  The first number is the amount 
of memory to reserve.  The second is the amount of memory to commmit 
to; that is, the amount of virtual memory to map into physical 
memory.  The reserve number must be bigger than the commit number.  
If you don't specify the commit amount, BLINK sets it to be the same 
as the reserve amount.  Note that with a reserve and a commit, the 
program will have a section of virtual memory that is reserved for 
the heap but is not actually mapped into physical memory.

Setting the stack size
----------------------
STACKSIZE number[,number]

Optional. Set the size of the stack.  The first number is the amount 
of memory to reserve.  The second is the amount of memory to commmit 
to; that is, the amount of virtual memory to map into physical 
memory.  The reserve number must be bigger than the commit number.  
If you don't specify the commit amount, BLINK sets it to be the same 
as the reserve amount.  Note that with a reserve and a commit, the 
program will have a section of virtual memory that is reserved for 
the stack but is not actually mapped into physical memory.

If you're compiling your program with ZTC, you don't need this 
statement, unless you want the stack to be larger than the size ZTC
set. 

Setting the stub program
------------------------
STUB 'filespec' 

Optional. Specify the stub program that runs when you try to use a 
Windows NT program under DOS. If you don't include this statement, 
BLINK uses a stub that prints "This program does not run in DOS 
mode." 

Specifying the I/O subsystem
----------------------------
SUBSYSTEM [ WINDOWS | CONSOLE | POSIX ]

Specify which I/O subsystem to use. Your definition file must 
include this statement. You can choose from these keywords:

WINDOWS         The program is a Windows program.
CONSOLE         The program is a text mode program.
POSIX           The program is a POSIX program

Setting the CODE segment's default attibutes
--------------------------------------------
CODE [READ] [WRITE] [EXECUTE] [SHARED]

Optional. Specify the default attributes for the executable's CODE 
segment.

READ            Let an executable read this segment's instructions.
WRITE           Let an executable write to this segment's 
                instructions. 
EXECUTE         Let an executable execute this segment's 
                instructions. 
SHARED          Let multiple applications use this segment at a 
                time. Use this option with DLLs only  

Setting the DATA segment's default attibutes
--------------------------------------------
DATA [READ] [WRITE] [EXECUTE] [SHARED]

Optional. Specify the default attributes for the executable's DATA 
segment.

READ            Let an executable read this segment's data.
WRITE           Let an executable write to this segment's data.
EXECUTE         Let an executable execute this segment's data.  
SHARED          Let multiple applications use this segment at a 
                time. Use this option with DLLs only  

Setting a segment's attibutes
-----------------------------
[SEGMENTS | SECTIONS] { name [CLASS 'class'] 
                        [minsize]
                        [READ] [WRITE] [EXECUTE] [SHARED] }

Option. Give attributes to a segment that is defined in one of the 
object files you're linking. Name is the name of the segment and 
class is the segment's class. Minsize is an optional number that 
specifies the minimum size of the segment. If the data in the object 
files is too small, the segment will be increased to minsize. If the 
data in the object files is greater than minsize, the segment will 
be the size of the data in the object files. 

READ            Let an executable read this segment.
WRITE           Let an executable write to this segment.
EXECUTE         Let an executable execute this segment.  
SHARED          Let multiple applications use this segment at a 
                time. Use this option with DLLs only.

Importing functions into an executable
--------------------------------------
IMPORTS { [extname=]module.entry }

Optional. Let this execuable use the listed routines, which are in 
DLLs. The module is the name of the routine's DLL and entry is 
either a number or an identifier. If entry is a number, then the 
entry with that number is linked in. If entry is an identifier then 
the entry with that name is linked in. Include an extname if this 
application calls the routine by a name that is different from the 
one in the DLL. The applications's DEF file doesn't need an IMPORTS 
statement for a particular DLL if you use an import libary for that 
DLL.

Exporting functions from a DLL
------------------------------
EXPORTS { pubname=intname
                 [@number [NONAME]] 
                 [CONSTANT] }

Let other executables use the listed routines, which are in this 
DLL. This option is for DLLs only. Pubname is the external name of 
the exported function (that is, the name used in an IMPORTS 
statement as the entry). Intname is the internal name: the name used 
within the DLL. 

@Number defines the export to be at a specific number (so another 
executable can import it with module.numeric_entry). If you specify 
NONAME, BLINK doesn't save the routines name. Otherwise, BLINK does 
save the name, so you can refer to it by both name and number. 

CONSTANT specifies that the name is a contant variable, not a 
function.
