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 (segment sizes are an issue). 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 (for example, `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 a `REDIST' directory on the Visual C++ CD-ROM disc. 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 originally developed with Microsoft Visual C++ Version 2.0, on Windows NT 3.5, and we now build on Windows NT 4.0 under Visual C++ 5.0. We have not tried with any other compiler. 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 versions 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. 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.4 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.

NOTE: You *must* build Python itself. ILU requires several symbols to be exported from the python.dll that are normally not normally exported. Before building Python, in the Python source tree, edit the file in the PC directory called python_nt.def, so as to also export the following symbols: start_new_thread init_thread get_thread_ident exit_thread (and for compatibility with pythonwin, PyArg_ParseTupleAndKeywords). Then follow the instructions in the PC/readme.txt file to build python. In addition to exporting these additional symbols, building Python yourself ensures that Python is using the same C runtime library as ILU. (Different C runtime libraries in use at the same time 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 no longer distributed with ILU.

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.4 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. Retrieve the python source from http://www.python.org, as python1.4.tar.gz.

2. Edit the file in the PC directory called python_nt.def, so as to also export the following symbols: start_new_thread init_thread get_thread_ident exit_thread and for compatibility with pythonwin, PyArg_ParseTupleAndKeywords).

3. Then follow the instructions in the PC/readme.txt file to build python. (Ensure that the resulting python14.dll is the dll that gets used by python.)

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

5. Set the PYTHONSRC environment variable appropriately, e.g. set PYTHONSRC=E:\Python-1.4src

6. 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 your on your PYTHONPATH.

10. 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.