 Variables: C Datatypes
 Variables: C DatatypesLisp variables may be passed to or received from C style functions that  take any of the standard C datatypes as parameters. C datatypes include  byte/char, short, int, float, and double. Corman Lisp transparently  takes care of much of the necessary casting and conversion between Lisp  and C variables. 
C
int width = 0;
int height = 0;
  
Lisp
(setf width 0)
(setf height 0)
  3.3) Variables: C Arrays and Structures
Things begin to get interesting when structures and arrays are used.  Pure Lisp arrays are not equivalent to C arrays and therefore it is not  possible to pass a Lisp array to a C function. If a C function takes an  array a C style array must be created from within Lisp.
 
C
static GLfloat v0[] = { -1.0f, -1.0f,  1.0f };
  When using C, arrays may be created on the stack as shown in the C  code above. When a C array is created in Lisp, it is always created on  the heap - meaning it must be created using malloc. Because Lisp  is garbage collected there is no need to explicitly free a variable  created using malloc. The garbage collector will automatically  free the memory for v0 when the variable goes out of scope.  Although there is nothing stopping the reader from explicitly freeing a  variable using the function free.
 
Lisp
(setf v0 (ct:malloc (ct:sizeof ‘(:single-float 3))))
  A C array may be initialized when it is created. In Lisp because C  arrays are created on the heap, assignment must take place as a separate  step.
 
Lisp
(setf (ct:cref (:single-float 3) v0 0) -1.0)
(setf (ct:cref (:single-float 3) v0 1) -1.0)
(setf (ct:cref (:single-float 3) v0 2) 1.0)
  cref (the ct: prefix identifies the package that  contains cref) is used for accessing a C style array, or structure.  Therefore, looking at the statements above:
 
ct:cref - accessing an array or structure.
(:single-float 3) - in this case, it is an array of 3 floats.
v0 - the name of the array we previously created using malloc.
0 - The index into the array
  The Lisp implementation seems backward compared to the C-style the  reader is probably used to, e.g v0[0] = -1. But that’s how it is done in  CCL. It is possible to improve upon this using macros
 The previous code described assignment. Retrieving a value is much  the same, but without the setf.
 
Lisp
(ct:cref (:single-float 3) v0 0)
-1.0
  The code for accessing a C struct is described below.
 
C
typedef struct {
 Sint16 x;
 Sint16 y;
 Uint16 w;
 Uint16 h;
} SDL_Rect;
  
Lisp
(setf a-rectangle (ct:malloc (ct:sizeof ’sdl:SDL_Rect)))
(setf (ct:cref sdl:SDL_Rect a-rectangle sdl::x) 120)
(setf (ct:cref sdl:SDL_Rect a-rectangle sdl::x) 200)
(setf (ct:cref sdl:SDL_Rect a-rectangle sdl::w) 64)
(setf (ct:cref sdl:SDL_Rect a-rectangle sdl::h) 64)
  The macro with-c-struct makes working with structs a  lot easier, as shown below:
 
(with-c-struct (x rectangle sdl:SDL_Rect)
   (setf
         sdl::x 120
         sdl::y 200
         sdl::w 64
         sdl::h 64))
  An important consideration is that the Lisp sizeof function  can only be passed defined types, for example sdl:SDL_Rect.  Calling sizeof on a variable such as a-rectangle will  fail.
 3.4) Functions
Calling C style functions in Lisp is straightforward.
 
C
SDL_Init( SDL_INIT_VIDEO );
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
  
Lisp
(SDL_Init SDL_INIT_VIDEO)
(SDL_GL_SetAttribute SDL_GL_RED_SIZE 5)
  3.5) Callbacks
defun-c-callback is used to create a function callback in Lisp.  As an example, the C prototype for the SDL function SDL_AddTimer is  shown below. SDL_AddTimer takes a function as one of its parameters and  calls that function at the specified interval.
 
C callback function prototype
typedef Uint32 (*SDL_NewTimerCallback)(Uint32 interval, void *param);
Lisp callback function
(ct:defun-c-callback timer-callback ((interval SDL:Uint32) (param (:void *)))
   (fformat “Yup, timer Fired”)
   (values interval))
  
C SDL_AddTimer prototype definition
SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param);
Lisp code using a callback
(setf param (ct:malloc (ct:sizeof :LONG)))