| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version |
This document contains the following sections:
1.0 IntroductionAllegro CL consists of three standard parts and one optional part:
Any Unix or Windows program may serve as a Lisp main program if it:
Linking the Allegro CL Shared Library is discussed in this document. Dynamically loading the Allegro CL Shared Library is more complicated and operating-system dependent and is not further discussed. Please contact Franz Inc. for more information if you are interested in that option (see introduction.htm).
Basic requisite code for a minimal Lisp main is given in the following sections. The main should be linked with the Allegro CL Shared Library and with any other shared or static libraries that are required for Allegro CL and application operation.
In the example below, the [version] in libacl[version].so is different for each release of Allegro CL. Find the correct name by looking in the Allegro directory.
struct shlib_library_item { char * name; int system; }; #include <stdio.h> #include "misc/shlibs.h" void my_exit( int ); main( int argc, char **argv, char **envp ) { /* put custom installation code here */ fprintf(stderr, "custom code runs..\n" ); lisp_init( /* these three arguments are the main() arguments */ argc, argv, envp, /* custom exit function; use 0 if default exit() call desired */ my_exit, /* directory containing Allegro CL shared library and Lisp image(s ) */ "/room2/test/src", /* Allegro CL shared library name; name could vary, so check your Allegro CL directory for the correct name */ "libacl[version].so", /* Allegro CL shared library handle or 0 if none, 0 for this use */ 0, /* default lisp image name; use 0 if no default desired */ "lisp.dxl", /* tls_slot_index 0 or 1, if 1 asks the Acldll to create its own thread-local index. See thread-local note below. This argument was 'quiet' in releases prior to 8.1 but not used. */ 0, /* Win32app flag; on UNIX, must be 0 */ 0, /* global variable containing prelinked library list; defined by shlibs.h include file */ linked_shared_libraries ); } void my_exit( int n ) { fprintf( stderr, "my exit code can run here\n" ); exit( n ); }
As of 8.1, lisp thread-local values will be stored directly in the
threads, rather than in the global table as they now are (thus
requiring them to be moved in and out as threads are switched). This
requires that Allegro CL be able to get one thread-local slot from the
operating system (because thread-local storage is limited in count on
some systems, we only require that one slot be provided, and we then
manage that slot in the lisp). Some systems don't even provide for
thread-local slots, or their provision has not been exploited yet;
these systems are marked with :no-os-tls
in the
*features*
list (this
name means "no operating-system supplied thread-local storage").
These architectures can supply a 0 or a 1 to the tls_slot_index
argument.
Also, most architectures can get a tls slot from within the acl shared library, though on some architectures there are very strict linking rules needed in order to do so. On the HP 64-bit port, which has tls, but whose shared-library cannot generate a tls slot, the tls_slot_index function pointer must be passed in.
The example is given in examples/linkacl/fact.c (on Unix machines, related example in examples/dll/fact.c on Windows). For HP, and for any other architecture which supports the relatively new __thread construct in C/C++, the code would look something like this:
#ifdef NeedTls __thread nat tls_dummy_slot; nat tls_slot_index() { return (nat)&tls_dummy_slot; } #endif and in the actual lisp_init, call where the quiet flag used to be: lisp_init( lnk_argc, lnk_argv, lnk_envp, /* argc, argv, envp */ 0, /* exit routine */ dir_buf, /* system directory */ (char*)LIBACL_NAME, 0, (char*)"fact.dxl", /* image name */ #ifdef NeedTls &tls_slot_index, #else (nat(*)())1, /* quiet flag (old) */ #endif 0, /* unused on Unix */ linked_shared_libraries );
For windows, the definition of tls_slot_index would be
nat tls_slot_index() { return ((nat)(TlsAlloc())); }
#include <windows.h> #include <process.h> unsigned _stdcall startlisp(void *x) { StartLisp((char *) x, 1, 1); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HANDLE handle; int lisp_thread_id; /* custom code can go here */ MessageBox(NULL, "custom code could run now", "before Lisp starts", MB_OK); handle = (HANDLE) _beginthreadex(0, 0, startlisp, (void *) lpCmdLine, 0, &lisp_thread_id); WaitForSingleObject(handle, INFINITE); /* custom code can go here; it runs after Lisp exits */ MessageBox(NULL, "custom code could run now", "after Lisp exits", MB_OK); return 0; }
StartLisp()
function is in
elm[version].dll (the name of this file will vary,
so check your Allegro CL directory for the correct name of this .dll
and the elm[version].lib). Assuming the above code is
in a file named testm.c, an executable named testm.exe
is produced by the command:testm -I allegro.dxl -e '(load "gdi32.dll")' -e '(load "user32.dll")' -e (load "kernel32.dll")' -e '(load "comctl32.dll")'
You may have problems building a custom executable (with a user-defined main()) on a version of Redhat later than the one on which your version of Allegro CL was built. If you run into this problem, please contact Franz Inc. Technical Support (send email to [email protected]).
Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 8.2 page.
Created 2012.5.30.
| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version |