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, etc.. 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++ 6.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.

Lisp

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.

Java

ILU's supports Java on Windows using either Javasoft's JDK 1.1 http://www.javasoft.com/products/jdk/1.1/index.html or JDK 1.2 http://www.javasoft.com/products/jdk/1.2/index.html, or Microsoft's SDK for Java 3.1 Release (Visual J++ 6 compatible) http://www.microsoft.com/java/download.htm . If you're using the Javasoft JDK, you should define the environment variable JAVASDK to Javasoft. If you're using Microsoft's SDK for Java 2.0 Beta 2 Release, you should define the environment variable JAVASDK to Microsoft. In both cases, the environment variable JAVA_HOME should be set to wherever the Java development software was installed, e.g. set JAVA_HOME=e:\jdk1.1.6, or set JAVA_HOME=e:\SDK-Java.20. Be sure your CLASSPATH environment variable includes the ILUHOME/lib/classes directory. e.g. set CLASSPATH=.:.\classes:e:\iluwin\lib\classes.

NOTE: In the Microsoft's SDK for Java 2.0 Beta 2 Release, you must modify the file JAVA_HOME\include\native.h to correctly reflect the fact that the function RNIGetCompatibleVersion is something exported from a dll to Java. i.e.:


#pragma message( "NOTE: ILU mod to native.h - Defining RNIGetCompatibleVersion as dllexport" )
/* originally  DWORD __cdecl RNIGetCompatibleVersion(); */
__declspec(dllexport) DWORD __cdecl RNIGetCompatibleVersion();


NOTE: An ilu build upon Javasoft's JDK 1.1.6 can be also be used from
applications within JBuilder 2, or, Visual Cafe 2.5.


ILU's support for Javasoft's JDK 1.2 needs a few environment variables set
accordingly:  You need to set the environment variable JAVA_HOME to the jre directory and the
JDK_HOME to the jdk directory.  Furthermore the mak file requires the environment variable JAVAUSE12 to be set.   

ILU's also used to support Java using Javasoft's JDK 1.2beta2 or JDK 1.2beta4 pre-release, but the build may be more tricky and no more recommended because
our testing does not include outdated beta releases.   



NOTE: Build a jar file and the javadoc files manually.


NOTE: It is possible to manually create a release directories containing all
Javasoft's JDK 1.1.6 support, JDK 1.2 support and Microsoft's SDK support in a friendly
co-existing way.  To do this with the current make files: build and install for
Microsoft first.  Then in a new shell (setup to build for Javasoft's JDK) you
can cd into the src\runtime\java directory and re-build just the java runtime.
Go back to the top and re-install ALL of ilu.  (Do it in this order, so that
the "better" files are installed later.  The three builds use non-conflicting
names for the one otherwise incompatible dll file; all other files are
compatible as long as you are not trying to single step or debug ilu itself).  The
build is not quite perfect: If building a further ilu system fails because existing files from the first
build interact badly, clean ilu (having set the environment variables for the later system) and build
ilu system again.  The clean step will leave the important file from the first build alone.


Python

By default, the Python Language Specific Runtime is only built if the environment variable PYTHONSRC is set to point to your Python Source directory which contains the Python Include directory, the Python PC directory, and (for Python 1.4, the Python vc40 directory containing python14.lib) (for Python 1.5.2, the PCBuild directory containing python15.lib).

If you need these files, please retrieve the Python source from http://www.python.org, as python1.4.tar.gz for Python 1.4, and pyth152.tgz for Python 1.5.2. They are NOT distributed with ILU.

Python 1.5.2 build is the default ILU Python runtime on Win32.

You will need to put ILUHOME/lib on your PYTHONPATH before using ILU with Python.

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

For Python 1.5.2, Ensure that you build the Python 'Release' Configuration as this is set up to use the Multithreaded C Runtime DLL. If you really want to build the 'Debug' version of Python, you must adjust the project to use the Multithreaded C Runtime DLL, NOT the Debug Multithreaded C Runtime DLL. Failure to do this will cause strange problems as ILU always uses Multithreaded C Runtime DLL. Also, if building the 'Debug' version of Python, you should adjust all references to python15.lib in the iluPr15.mak file to reflect its true location.

Also, if you're trying to build a debug version of ILU, you'll find that the python runtime build gets a link error complaining about python15_d.lib. This is because the PYTHONSRC\PC\config.h file is set up to force the use of python15_d.lib if _DEBUG is defined. You can get around this by editing the config.h file as follows:

#ifndef USE_DL_EXPORT
/* So nobody needs to specify the .lib in their Makefile any more */
//#ifdef _DEBUG
//#pragma comment(lib,"python15_d.lib")
//#else
#pragma comment(lib,"python15.lib")
//#endif
#endif /* USE_DL_EXPORT */

For Python 1.4, 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. Next change the line for 'ALL' in $(ILUSRC)\runtime\python\iluwin32.mak to ALL : PMAKE14 before building ILU's Python 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.

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 1.4 support - details

This release of ILU supports both Python 1.4 Python 1.5.2 (the default) for Windows. If you want to use Python 1.4, building it as described in the previous Python section of this chapter is a bit involved. 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.