Platform-Specific Issues for Euphoria
Euphoria programs can currently run on three different platforms. More platforms will be added in the future. The first platform is called DOS32, since it depends on the DOS operating system, but with the CPU operating in 32-bit (protected) mode. The second platform is called WIN32, since the underlying operating system is Microsoft Windows, in particular, the 32-bit version of Windows that is used on Windows 95/98 and Windows NT. The third platform is Linux. Linux is based on the UNIX operating system. It has recently become very popular on PCs. Linux on the PC is also a 32-bit system. The Euphoria for DOS32+WIN32 .zip file contains two .exe files. The first is called ex.exe. It runs Euphoria programs on the DOS32 platform. The second is exw.exe. It runs Euphoria programs on the WIN32 platform. Euphoria programs that are meant to be run on the WIN32 platform have a .exw file type, while programs that are meant to be run on the DOS32 platform have a .ex file type. The Euphoria for Linux .tar file contains only exu. It runs Euphoria programs on the Linux platform. Euphoria programs intended for Linux have a .exu file type. Many Euphoria programs can be run on two, or all three platforms without change. The file type should indicate the preferred platform for the program. Any Euphoria interpreter will try to run any Euphoria file. You just have to specify the full name of the file, including the type. Sometimes you'll find that the majority of your code will be the same on all platforms, but some small parts will have to be written differently for each platform. Use the platform() built-in function to tell you which platform you are currently running on.
If you are new to programming, you should start off with ex.exe on the DOS32 platform, or perhaps exu on the Linux platform. Windows programming is somewhat more complicated, no matter which language you use. Programs run in 32-bit (protected) mode and have access to all of the megabytes of memory on the machine. Most programming languages for DOS limit you to 16-bit real mode. This makes it impossible to access more than 640K of memory at one time. Your machine might have 32Mb of memory, but your program will run out of memory after using 640K. QBasic is even worse. It limits you to just 160K. DOS32 programs are typically run with the screen in either text mode or pixel graphics mode, and there is a large library of Euphoria routines that you can call. There is rarely any need to call DOS directly, but you can do this using the dos_interrupt() routine. You can also peek and poke into special memory locations to achieve high-speed graphics and get access to low-level details of the system. Under DOS32 for Windows 95/98, Euphoria files can have long filenames, and programs can open long filename files for reading and writing, but not for creating a new file. Under pure DOS, outside of Windows, there is no system swap file so the DOS-extender built in to ex.exe will create one for possible use by your program. This file is created when your Euphoria program starts up under DOS, and is deleted when your program terminates. It starts as a 0-byte file and grows only if actual swapping is needed. It is created in the directory on your hard disk pointed to by the TEMP or TMP environment variable. If neither of these variables have been set, it is created in the directory containing either ex.exe or your bound Euphoria .exe file. You can force it to be created in a particular directory by setting the CAUSEWAY environment variable as follows: SET CAUSEWAY=SWAP:pathwhere path is the full path to the directory. You can prevent the creation of a DOS swap file with: SET CAUSEWAY=NOVM When disk swapping activity occurs, your program will run correctly but will slow down. A better approach might be to free up more extended memory by cutting back on SMARTDRV and other programs that reserve large amounts of extended memory for themselves. When your free disk space is less than the amount of RAM in your machine, no swap file will be created. Euphoria for WIN32 (exw.exe) has a lot in common with Euphoria for DOS32. With WIN32 you also have access to all of the memory on your machine. Most library routines work the same way on each platform. Many existing DOS32 text mode programs can be run using exw without any change. With exw you can run programs from the command line, and display text on a standard (typically 25 line x 80 column) DOS window. The DOS window is known as the console in Windows terminology. Euphoria makes the transition from DOS32 text mode programming, to simple WIN32 console programming, trivial. You can add calls to WIN32 C functions and later, if desired, you can create real Windows GUI windows. A console window will be created automatically when a WIN32 Euphoria program first outputs something to the screen or reads from the keyboard. Currently, you will also see a console window when you read standard input or write to standard output, even when these have been redirected to files. The console will disappear when your program finishes execution, or via a call to free_console(). If there is something on the console that you want your user to read, you should prompt him and wait for his input before terminating. To prevent the console from quickly disappearing you might include a statement such as: if getc(0) then end ifwhich will wait for the user enter something. Under WIN32, long filenames are fully supported for reading and writing and creating.
Thanks to David Cuny, there is a package called Win32Lib that you can use to develop Windows GUI applications in Euphoria. It is remarkably easy to learn and use, and comes with good documentation and many small example programs. You can download the file win32lib.zip from the Euphoria Web site. David has also developed a compatible package for DOS32, called Dos32Lib. In many cases you can write a simple program that will work using Win32Lib on Windows, and by changing one include statement, the program will also run on DOS. Recently, Gary Dumer has started to develop the Visual Euphoria Library, VEL, which offers Euphoria programmers another excellent way to develop Windows GUI programs.
To allow access to WIN32 at a lower level, Euphoria provides a mechanism for calling any C function in any WIN32 API .dll file, or indeed in any 32-bit Windows .dll file that you create or someone else creates. There is also a call-back mechanism that lets Windows call your Euphoria routines. Call-backs are necessary when you create a graphical user interface. To make full use of the WIN32 platform, you need documentation on 32-bit Windows programming, in particular the WIN32 Application Program Interface (API), including the C structures defined by the API. There is a large WIN32.HLP file (c) Microsoft that is available with many programming tools for Windows 95/98 or Windows NT. There are numerous books available on the subject of WIN32 programming for C/C++. You can adapt most of what you find in those books to the world of Euphoria programming for WIN32. A good book is:
by Charles Petzold Microsoft Press
A WIN32 API Windows help file (8 Mb) can be downloaded from Borland's
Web site: See also the Euphoria Archive Web page - "documentation". Euphoria for Linux shares certain features with Euphoria for DOS32, and shares other features with Euphoria for WIN32. As with WIN32 and DOS32, you can write text on a console, or xterm window, in multiple colors and at any line or column position. Just as in WIN32, you can call C routines in shared libraries and C code can call back to your Euphoria routines. Euphoria for Linux does not have integrated support for pixel graphics like DOS32, but Pete Eberlein has created a Euphoria interface to svgalib. X windows GUI programming is currently possible using Irv Mullin's interface to the graphapp package. David Cuny is planning to port his new Llama GUI package from WIN32 to Linux. When porting code from DOS or Windows to Linux, you'll notice the following differences:
On WIN32 and Linux it's possible to interface Euphoria code and C code. Your Euphoria program can call C routines and read and write C variables. C routines can even call your Euphoria routines. The C code must reside in a WIN32 dynamic link library (.dll file), or a Linux shared library (.so file). By interfacing with .dll's and shared libraries, you can access the full programming interface on both of these systems.
To call a C function in a .dll or .so file you must perform the following steps:
See library.doc for descriptions of c_func(), c_proc(), define_c_func(), define_c_proc(), open_dll() etc. See demo\win32 or demo\linux for example programs. You can examine a .dll file by right-clicking on it, and choosing "QuickView" (if it's on your system). You will see a list of all the C routines that the .dll exports. To find out which .dll file contains a particular WIN32 C function, run euphoria\demo\win32\dsearch.exw.
You can get the address of a C variable using
define_c_var().
You can then use poke() and peek() to access the value of the variable.
Many C routines require that you pass pointers to structures. You can simulate C structures using allocated blocks of memory. The address returned by allocate() can be passed as if it were a C pointer. You can read and write members of C structures using peek() and poke(), or peek4u(), peek4s(), and poke4(). You can allocate space for structures using allocate(). You must calculate the offset of a member of a C structure. This is usually easy, because anything in C that needs 4 bytes will be assigned 4 bytes in the structure. Thus C int's, char's, unsigned int's, pointers to anything, etc. will all take 4 bytes. If the C declaration looks like: // Warning C code ahead! struct example { int a; // offset 0 char *b; // offset 4 char c; // offset 8 long d; // offset 12 }; To allocate space for "struct example" you would need: atom p p = allocate(16) -- size of "struct example" The address that you get from allocate() is always at least 4-byte aligned. This is useful, since WIN32 structures are supposed to start on a 4-byte boundary. Fields within a C structure that are 4-bytes or more in size must start on a 4-byte boundary in memory. 2-byte fields must start on a 2-byte boundary. To achieve this you may have to leave small gaps within the structure. In practice it is not hard to align most structures since 90% of the fields are 4-byte pointers or 4-byte integers. You can set the fields using something like: poke4(p + 0, a) poke4(p + 4, b) poke4(p + 8, c) poke4(p +12, d)You can read a field with something like: d = peek4(p+12)
When you create a window, the Windows operating system will need to call your Euphoria routine. This is a strange concept for DOS programmers who are used to calling operating system routines, but are not used to having the operating system call their routine. To set this up, you must get a 32-bit "call-back" address for your routine and give it to Windows. For example (taken from demo\win32\window.exw): integer id atom WndProcAddress id = routine_id("WndProc") WndProcAddress = call_back(id)routine_id() uniquely identifies a Euphoria procedure or function by returning a small integer value. This value can be used later to call the routine. You can also use it as an argument to the call_back() function. In the example above, The 32-bit call-back address, WndProcAddress, can be stored in a C structure and passed to Windows via the RegisterClass() C API function. This gives Windows the ability to call the Euphoria routine, WndProc(), whenever the user performs an action on a certain class of window. Actions include clicking the mouse, typing a key, resizing the window etc. See the window.exw demo program for the whole story.
The values that are passed to your Euphoria routine can be any 32-bit unsigned atoms, i.e. non-negative. Your routine could choose to interpret large positive numbers as negative if that is desirable. For instance, if a C routine tried to pass you -1, it would appear as hex FFFFFFFF. If a value is passed that does not fit the type you have chosen for a given parameter, a Euphoria type-check error may occur (depending on with/without type_check etc.) No error will occur if you declare all parameters as atom. Normally, as in the case of WndProc() above, Windows initiates these call-backs to your routines. It is also possible for a C routine in any .dll to call one of your Euphoria routines. You just have to declare the C routine properly, and pass it the call-back address. Here's an example of a WATCOM C routine that takes your call-back address as its only parameter, and then calls your 3-parameter Euphoria routine: /* 1-parameter C routine that you call from Euphoria */ unsigned EXPORT APIENTRY test1( LRESULT CALLBACK (*eu_callback)(unsigned a, unsigned b, unsigned c)) { /* Your 3-parameter Euphoria routine is called here via eu_callback pointer */ return (*eu_callback)(111, 222, 333); }The C declaration above declares test1 as an externally-callable C routine that takes a single parameter. The single parameter is a pointer to a routine that takes 3 unsigned parameters - i.e. your Euphoria routine. In WATCOM C, "CALLBACK" is the same as "__stdcall", i.e "standard call". This is the calling convention that's used to call WIN32 API routines, and the C pointer to your Euphoria routine must be declared this way too, or you'll get an error when your Euphoria routine tries to return to your .DLL. Note that the default calling convention for Windows C compilers is something different, called "__cdecl". In the example above, your Euphoria routine will be passed the three values 111, 222 and 333 as arguments. Your routine will return a value to test1. That value will then be immediately returned to the caller of test1 (which could be at some other place in your Euphoria program).
|