Go to the previous, next section.

Using ILU with Microsoft Windows

Note: In this document, when you see a reference to Windows, it applies to Windows 95, Windows NT 3.5 and Windows NT 4.0. Windows 3.1 is no longer supported, since ILU makes assumptions about the size of items that can be copied via certain system/library calls. For this reason, ILU under Windows 3.1 will only work reliably in all situations with other Windows 3.1 systems running ILU.

Prerequisites for using ILU with Microsoft Windows

Using ILU applications on Windows NT and Windows 95

Windows must be set up to use TCP/IP. Use the Network Configuration and Control Applet under the Windows NT control panel to install and configure your TCP/IP setup. For Windows 95, use the Network applet. (See your Windows documentation for further details.) Try all the usual TCP/IP applications (e.g. ping, ftp, telnet) to ensure your TCP/IP is working properly. You will also need the redistributable Microsoft C Runtime dynamic link library for NT (`MSVCRT20.DLL' if using Visual C++ 2.0 or `MSVCRT40.DLL' if using Visual C++ 4.0) on the system. The Visual C++ redistributable files are located in the `\MSVC20\REDIST' directory on the Visual C++ Version 2.0 CD-ROM disc, or in the `\MSDEV\REDIST' directory on the Visual C++ 4.0 CD-ROM. Note that versions of Visual C++ later than 4.0 actually have additional DLLs (`MSVCRT.DLL') that contain the "real" runtime library. If you've installed Visual C++, then most likely you have the necessary DLLS installed. [Note - you can determine what dlls a dll or exe imports by using the dumpbin utility that comes with Visual C++.]

Be careful to use the right Visual C++ runtime DLL. In particular, Windows 95 ships with one version of the DLL in the `\WINDOWS\SYSTEM' directory, since many of the Windows 95 system applets are written with Visual C++.

Prerequisite software to use AND develop ILU applications on Windows NT and 95.

This release of ILU for Windows NT was developed with Microsoft Visual C++ Version 2.0, on Windows NT 3.5, and was later built on Windows NT 4.0 under Visual C++ 4.2. It has not been tried with any other compiler or version of NT. The ILU runtime DLLs for NT are 32 bit, and a 32 bit compiler is needed to develop applications that use them. If you succeed in building ILU or ILU applications for NT with a compiler other than Microsoft Visual C++, please report your findings. We simply haven't had time to test ILU with other C or C++ compilers with Windows.

Typically, we move to the latest version of Visual C++ as soon as it has been shipped to us. There is nothing known in ILU that should prevent it from being built with earlier version of Visual C++.

Installation

ILU comes prebuilt for Windows NT. For the current release of ILU, a single `.ZIP' file is the prebuilt version. The `.ZIP' file is created with Nico Mak Computing's WINZIP, which allows long file names and is available for all versions of Windows. However, if you only have PKZIP, you should be able to extract the files from the `.ZIP' with no problems. Just make sure you use the -d when unzipping so that PKZIP will preserve the directory structure contained within the `.ZIP' file. You should also be aware that we use long filenames for some of the stubbers, so older versions of PKZIP might truncate the filenames as the files are extracted.

Determine where you wish to install ILU, e.g. `C:\ILUWIN'. Set the environment variable ILUHOME to this directory (ILUHOME is needed for building the examples). Unpack the distribution into your installation directory using pkzip -d iluwin.zip (or, if using WINZIP, just open the `.ZIP' archive and press the "Extract" button). You should now have subdirectories in ILUHOME called `bin', `examples', `include', `interfaces' and `lib'.

If you'll be developing ILU apps, or building the examples, set the environment variable ILUPATH to include `ILUHOME\interfaces' ILUPATH is the path of directories where interface (`.isl') files can be found. For example, setting ILUPATH to `.;C:\ILUWIN\INTERFACES' will cause ILU stubbers to look for interfaces first in the current directory, then in `C:\ILUWIN\INTERFACES'. Add the `ILUHOME\bin' directory to your PATH environment variable.

Determine what common directory share will be used for your applications to publish information about ILU objects. This will commonly be a directory that is exported from a file server and shared by all the systems. Set the environment variable ILU_BINDING_DIRECTORY to this directory e.g. ILU_BINDING_DIRECTORY=f:\iluwin\bindings. If you do not set this, ILU will default to whatever value is specified in the file `iluwin.h'.

Building ILU

(For those who just *must* have and build the source! :-)

If you wish to build the ILU system from source, begin by obtaining the source distribution (`ilu.tar.gz'). There is no separate source tree for the Windows version; the same source code is used for both Unix and Windows. Set ILUHOME to where you will want ILU to be installed. Determine where you wish to install the ILU source, and set the environment variable ILUSRC to that directory e.g. `ILUHOME\src'. Unpack the distribution into that directory. Change to the ILUSRC directory. Having previously installed Visual C++, perform

> nmake -f iluwin32.mak
To subsequently install into ILUHOME, perform

> nmake -f iluwin32.mak install
Note that the default is to build a 'release' version. If you wish to build a 'debug' version perform

> nmake -f iluwin32.mak CFG="Win32 Debug"
To clean up after installation perform

> nmake -f iluwin32.mak clean

Various #defines that determine how ILU is built can be found in the file `ILUSRC/runtime/kernel/iluwin.h'.

When bulding the debug versions of the c, c++, and kernel runtimes, the values of the environment variables, ILU_DEBUG_CFLAGS and ILU_DEBUG_CPPFLAGS are passed to the c and c++ compiler command lines respectively. This allows the builder to do things like creating source browser files, e.g. set ILU_DEBUG_CFLAGS=/FR"/ilu/browsefiles/", set ILU_DEBUG_CPPFLAGS=/FR"/ilu/browsefiles/".

Note: "make clean" does not work across all versions of Windows. In particular, it will not work on systems other than Windows NT. If you are using Windows 95, just remove all occurrences of the `WinDebug', `WinDebugW', `WinRel', and `WinRelW' directories in the source tree and examples directories. You can also safely delete any .map, .ilk, .exp, and .pdb files you might see.

Note that it is normal to see a number of compiler warnings during the ILU build process. It's also been reported that linking in the build can fail if the full Visual C++ has not been installed. This is because the makefiles used were originally generated by the MSVC Development Environment, which by default adds a whole slew of libraries to the link command, e.g. odbc32.lib (even though ilu doesn't need them, apparently the link fails because they cannot be found). The workaround is to fully install Visual C++, or go modify the makefiles to take out those references.

If you would like to use Allegro Lisp for Windows with ILU, you will have uncomment the appropriate lines in the `ILUSRC/stubbers/lisp/iluwin32.mak' and `ILUSRC/runtime/lisp/iluwin32.mak' makefiles, as these components are not built by default. Note that the Allegro Lisp for Windows support was graciously contributed by Joachim Achtzehnter and has not been tested at PARC. Joachim reports that when using a Release build of ILU with Allegro Lisp for Windows, the makefile compilation switches in the makefiles for `ILUSRC/runtime/lisp' and `ILUSRC/runtime/kernel' should be changed from /Ox /Oy- to /Ob1 /Oi /Ot /Gs. For more information, see http://vanbc.wimsey.com/~joachim/ilu.html.

For those of you who want to use Python for Windows with ILU, you will have to make several changes. ILU has been tested with Python 1.3 and does work fine. However, the default build process will not build the Python/ILU runtime, since it needs to know where the Python header files are located. You will need to set the environment variable PYTHONSRC to point to the top of the Python distribution, and uncomment the obvious line in the makefile `ilupr.mak' for the Python/ILU runtime. You will also need several additional libraries that are built when Python itself is built. While a `.ZIP' file of these libraries is available on the ILU ftp site, it is *highly* recommended that you go get the Python distribution for Windows and build it yourself. Why? Because if you use a different version of Visual C++ than we did to build the Python distribution, you'll run into problems since ILU will be using one version of the Visual C++ runtime library, and the Python distribution will be using another version. This will result in bizarre, hard-to-track-down behavior.

So, the rule is: If you're going to build ILU from the source tree, and you want to use Python, build Python yourself first!

Building the examples

To build the examples, cd to `ILUHOME\examples'. Ensure that you have set ILUPATH as previously discussed.

For Windows examples, perform

> nmake -f iluwin32.mak

If you wish to build a 'debug' version perform

> nmake -f iluwin32.mak CFG="Win32 Debug"

This will create the example executables in subdirectories of the `example' subdirectories, called `WinRel' and `WinRelW' (or `WinDebug' and `WinDebugW' if you built a debug release) which correspond to the non-Windows and Windows versions of the examples.

Note that it is normal to see a number of compiler warnings during the examples build process.

Running the examples

Ensure that you have set ILU_BINDING_DIRECTORY as previously discussed. The non-Windows NT examples operate just like their Unix counterparts. The Windows examples are simple Windows versions of the same programs. To execute them, launch the executables (from the Windows File Manager, a command prompt (if you are running Windows NT or 95, or whatever), and choose the 'Run' entry from the 'Action' menu.

Developing Windows Applications with ILU

The basic process for using ILU in a Windows application is simple. You either write a new interface description or use an existing one. You run the stubbers against the interface description to generate stub code. You write calls to the methods exported from the interface in your application, or implement the object type in your application, depending on whether you're using the module, or providing it. Finally, you link your application code together with the generated stub code and the ILU libraries.

All Applications

Ensure that WIN32 is defined to the preprocessor when building a 32 bit ILU application. This is normally set by default by Visual C++, but you should verify.

You need to link with the language specific runtime, the kernel runtime, and the winsock library.

Set the Visual C++ code generation compiler option to use the Multithreaded using DLL C runtime on Windows NT. This is very important. If you don't do this, then you'll run into a similar problem that was described above for the Python runtime. Essentially, if you create an application that doesn't use the Mutithreaded DLL runtime library, then the ILU kernel will be using one copy of the runtime library, and your application will be using a completely different one. This will cause all sorts of bizarre behavior. If you are debugging your application and you get all sorts of ASSERTs about memory allocation arenas, you've made this mistake.

There is NO need to call ilu_StartWinsock for a Windows NT ILU app. (It is taken care of for you internally in the runtime DLL process attach code).

Windows (non-console) Applications

We suggest you review and understand the test1 examples before you try to build a windowed ILU application. This section tries to highlight some of the important points. Admittedly, the Windows examples are simple and crude as Windows apps go, but they illustrate what you need to do in an application.

In C++ ILU apps, you'll be including `Windows.h'. However, `Windows.h' includes `winspool.h' and this file #defines AddPort as AddPortA. This interferes with iluServer::AddPort(), so you have to undefine it (temporarily at least). See the `examples\test1\cppsrvrw.cpp' file for an example.

Message Loop

See the windowed test1 server examples for a simplistic timer based means of using ILU in the presence of a Windows message loop. (`msgalarm.c'). You'll want to do something about the message loop since otherwise your Windows app won't service the GUI - it'll just be blocked in an internal call to select() waiting to deal with ILU activity. This simple timer approach makes use of the ability to associate an 'alarm' function with the ILU mainloop. When the alarm goes off (the example uses every 500 milliseconds), the alarm function processes any Windows messages that are waiting, then sets the alarm for another period. Note that the test1 examples were developed with Microsoft's TCP/IP for Windows for Workgroups. Some of the behavior may be different under a different winsock implementation (especially with respect to message dispatch during select() calls). If so, please let us know.

Windows and the ILU_DEBUG settings

The "Debugging" chapter of this manual describes the facilities available to ILU developers for tracking down problems in their applications. One of these facilities is the ILU_DEBUG variable. When set to a value, it causes the ILU kernel and runtime to output various debugging messages.

For applications running under the Unix operating system, all output is sent to the stderr file handle, which can be redirected via the normal shell redirection operators. However, under Windows, this same flexibility is missing, since the Windows "shell" (`CMD.EXE' or `COMMAND.COM', depending on which version of Windows you are running) doesn't have the same flexbility. Programs that aren't console applications have an additional problem: they don't have any place for the output to go, since so-called "Windowed-API" applications detach themselves from consoles if they are executed from a command line.

The debug module in ILU has special code to handle this situation under Windows. Whether or not ILU outputs any messages depends on the "Debug Level" setting. This can be set two ways: either using the ILU_DEBUG environment variable, or via the ilu_SetDebugLevel() function (see `debug.c' for the whole story).

Normally, when the ILU kernel loads, it checks to see if ILU_DEBUG is set. If it is, it sets the appropriate debug level in the kernel, and then provides an internal error handler who's only job is to take the messages sent out by the kernel and write them to stderr. Of course, there is a function available to let you specify your own error handler. Just keep in mind that if you don't provide an error handler, and the kernel outputs a message because of ILU_DEBUG or ilu_SetDebugLevel() being called, then (by default), the debug messages will be sent to stderr.

If you are working with a console-based application under Windows, then this is not a problem. The messages will appear in the console that your application owns. Unfortunately, you can't redirect them to a file via the command line, since the Windows shell won't let you redirect arbitrary file handles. You can use ILU_DEBUG_FILE to redirect debug messages to a named file.

But, if you are working with a "real" Windows program, there is no console, and sending anything to stderr causes no output (since Windows equates stderr to the bit-bucket for Windowed-API applications). If you don't take any actions, then the kernel will handle this for you. If the debug level gets set (under Windows), the kernel attempts to figure out if your application is Windows-based or console-based. If it's console-based, then the normal debug-output functions are used.

However, if it appears that you are running a Windows-based application, and you have not provided an debug-handler of your own, then the kernel will create "Debug Console" and send all the debug output there for you.

This means that if you would like to set ILU_DEBUG, and your application is not console-based, then you don't have to do anything special to see the debug output. It's handled for you.

There are several things to keep in mind about this. The kernel has a very narrow-minded view of how to handle this. If you create your own debug handler, and you want to have the debug messages sent to you, *don't* set ILU_DEBUG. Instead, have your application set the debug level *after* you have installed your debug handler. If a debug handler other than the default gets installed, the code in `debug.c' will assume that you are going to handle it automatically, and it won't set up a debug console.

The way to determine if your application is console-based or Windows-based is to attempt to create a console (if you know a better way to determin this, please pass it on). This is what the kernel does; if the call to the WIN32 API call AllocConsole() succeeds, the kernel assumes (rightly) that your application doesn't have a console, and thus is a Windowed-API application. But, if your app is a Windowed-API application, and you create your own console before the kernel does, then AllocConsole() will fail, and the kernel will use *your* console (which may not be what you want).

So, just keep this is mind: If your application is a Windows app, then setting ILU_DEBUG will work for you. Just remember that if you want to capture the debug output yourself, you have to make sure and set up your handler *before* the debug level gets set in the kernel. See the code in `debug.c' for the whole story

WINIO

Note: ILU no longer needs WINIO. If the kernel or a runtime needs to output a message: if the application is a console app, output will go to that console; else the application must be a Windows app, and ILU will create a console window to which output will be sent.

WINIO is still distributed in the hope that it might be useful. However, it is important to keep in mind that it was not written by PARC. It's use in the past was to allow us to port the stubbers to Windows 3.1, and to provide a means of output for messages from the ILU runtimes and kernel in non-console (i.w. Windows) programs. We've also noticed that WINIO doesn't always work properly on Windows NT 4.0. The following is Obsolete: It no longer applies to ILU - For information only!

ILU was originally developed for Unix machines where there is always a notion of standard input and output. Error and Debug messages from the ILU runtime are sent to standard output. With Windows NT console applications, this same model is present. However with Windows 3.1 applications there is no notion of a console to which standard input and output can be applied (although under Windows NT you can programatically create a console; that is not addressed here). To provide a place for the ILU runtime to write standard output, the winio library is used. The winio library in ILU is an extension of the original very useful utility by Dave Maxey and Andrew Schulman - discussed in the Microsoft Systems Journal, 1991 #4 (July-Aug). When used properly, it causes an additional window to appear along with your application window, to which ILU runtime standard output (and yours too if you want to use a few printf's) is sent. Try setting ILU_DEBUG (as described in the ILU Reference manual) and you'll see the debug output get sent to the winio console window. If you make any nifty mods to this helpful library please pass them on!

To use the winio library, be sure to define _WINIO to the preprocessor when building a Windows ILU application, and tell the linker to include the winio library. You'll also likely want an icon for the console icon. This icon should be called WINIO_ICON. That is, you'll have an line in your resource file (.rc file) like:

WINIO_ICON              ICON    DISCARDABLE     "clnconsl.ico"

Your WinMain function will also contain a call (probably before you do your ShowWindow call) to create the console window that looks something like:

winio_console(hInstance, hPrevInstance, nCmdShow, 0, "clientw Console");

See the `WINIO.H' header file for a description of winio functionality. For more information, see the Microsoft Systems Journal, 1991 #4 (July-Aug), and the ILU winio source code.

Misc.

This section contains a 'hodge-podge' of information - with little attention paid to formatting.

Python support.

This release of ILU supports the version of Python 1.3 for Windows. However, by default, the Python/ILU runtime support is NOT built when building from the source distribution. Instead, you will get a message informing you that you need certain files before you can build the Python/ILU DLL. Specifically, here's what you need to do:

Assuming we don't have Python at all on the machine.

1: Obtain Python Binary distribution from http://www.python.org/ftp/python/pythonwin/pythonwin-09-6.exe

2. Install Python Binary distribution. Install directory I used is E:\Python1.3

3. Make the directory e:\PythonSRC

4. Either

A. Obtain just the the necessary files (win32_ilu_python_src.zip) from the ilu pages and put them into e:\PythonSRC

OR

B. Do it from scratch as follows:

1. Download the Unix sources from http://www.python.org/ftp/python/src/python1.3.tar.gz into e:\PythonSRC.

2. Change directory to e:\PythonSRC

3. Run gzip -d python1.3.tar.gz

4. Run tar -xf python1_3_tar You should now have a directory E:\PythonSRC\Python-1.3 containing the unix sources.

5. Download the Windows sources from http://www.python.org/ftp/python/pythonwin/pythonwin-src-09-5.zip and unzip this directly on top of the unix sources - i.e. extract (with overwrite existing files on) to E:\PythonSRC\Python-1.3.

6. Download MORE Windows sources from http://www.python.org/ftp/python/pythonwin/python-src-130-2.zip and unzip this directly on top of the unix sources - i.e. extract (with overwrite existing files on) to E:\PythonSRC\Python-1.3.

7. Download the Windows library files Windows from http://www.python.org/ftp/python/pythonwin/python-libs-09-5.zip and unzip this directly on top of the unix sources \lib directory - i.e. extract (with overwrite existing files on) to E:\PythonSRC\Python-1.3\lib

8. Copy the file Pythonc.lib into E:\PythonSRC\Python-1.3\lib. [Pythonc.lib is a library that results from building python that is not part of the regular python binary distributions. You can obtain it prebuilt from the ilu pages]

5. Go to ILUSRC\runtime\python and comment out the line in the makefile to allow the build of the runtime.

6. set PYTHONSRC=E:\PythonSRC\Python-1.3

7. If you DON'T want thread support in Python, remove or comment out the line #define ILU_PYTHON_THREADS 1 from the file ILUSRC\runtime\python\pythonversion.win

8. Make ILU - you should now have the file iluPr.pyd in the appropriate build subdirectory of ILUSRC\runtime\python.

9. Make Install ilu - This will copy the *.py files in ILUSRC\runtime\python to ILUHOME\lib. Be sure to put \ILUHOME\lib on yout on your PYTHONPATH.

10. Whew! -- Enjoy.

You can run several of the Python examples from ILU (the Python versions of Test1 and Bank work; Reconnect needs one change to work; change "import socket" to "import _socket").

Alternative Binding Service

The ilu binding service (in ILUSRC/etc/sbserver) is not built under Windows. Basically, the steps to build it are:

Step 1: Modify the makefile for the ILU kernel to include sbilu.obj instead of sbfile.obj. If you are building the kernel from scratch and don't care about dependencies, just replace "sbfile" with "sbilu" everywhere you see it in ilu32.mak.

Step 2: Modify the iluwin.h configuration header file to set the necessary parameters for the service. Specifically, these are the lines you need to worry about:

/* Define this to be the value of the ILU simple binding directory, if using shared files for simple binding */ #if !defined(ILU_BINDING_DIRECTORY) #define ILU_BINDING_DIRECTORY "\\project\\rpc\\current\\lib\\binding" #endif

Make sure that ILU_BINDING_DIRECTORY is *not* set to a value anywhere in the system. As you can see from the text, it gets automatically set if you haven't assigned a value. Comment out these lines so that it doesn't get set. The system decides what type of binding to use based on ILU_BINDING_DIRECTORY having a value or not.

/* Define this to be the domain of the simple binding server, if using ILU service for simple binding */ /* #undef ILU_BINDING_REALM */

/* Define this to be the host ip addr of the simple binding server, if using ILU service for simple binding */ /* #undef ILU_BINDING_HOST */

/* Define this to be the network port on the binding host, if using ILU service for simple binding */ /* #undef ILU_BINDING_PORT */

You'll need to uncomment these #defines and give them the appropriate values. See iluconf.h for more information about these variables.

Once you've done all this, you can make the kernel and it will have the simple binding service enabled and working.

The /ilu/etc directory contains directories called sbfile and sbserver. Between the two of them, you can build the simple binding server for Windows.

Borland C

ILU source does not build with Borland C, but some successful attempts have been reported. Here are some of the hints that have been passed back.

Borland doesn't prepend an underscore on Unix-based lib functions - all the various calls in "runtime/kernel/os/win.h

Header files - doesn't like declarations of partially typed variables. e.g. just saying extern struct _ilu_DefaultAlarm_struct. This forces the definition of the entity in the header file, requiring it to be removed from the source file where it is currently fully defined.

.def files need to have the VERSION keyword removed, and .def files that reference functions need to be changed to reference those functions without underscores. Microsoft uses underscores, Borland doesn't.

Whatever method you use for building ILU, make sure and set the "Max errors and warnings" to 0 (don't stop). ILU generates a number of warnings when build with Borland, and not setting this will cause the build to fail with a "too many warnings" error.

Don't enable CodeGuard (Borland's C/C++ memory check library; it looks for leaks and other nasties and logs them). It will have a field day with ILU since some parts of the system leak on purpose, like the stubbers.

Files in the distribution

Note: this list is in the process of being updated, and may contain some errors.

bin directory

lib directory

(Note unlabeled entries are the import libraries for their counterparts in the bin directory)

include directory (header files need for building ILU apps)

interfaces directory

examples directory

examples/httest

examples/iioptest1

examples/test1

examples/test2

examples/timeit

Go to the previous, next section.