[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Foreign Function Interface (long)



>2.	Is there anyway to redirect C stdout output to the LISP listener
>window?  I am using someone else's C code which has lots of printf
>statements that I am currently forced to ignore from within LISP.
>
>Thank you.
>
>Tara Cox
>University of Pittsburgh
>Department of Human Genetics

I can't help with your first problem, but perhaps I can contribute to
a solution for the second.  I don't believe that there is any easy way
to redirect stdout.  For the MPW C compiler printf will direct output
to an MPW window, but running under LISP you are out of luck.  
However, the conversion to something that will work may not be too
hard.  Here at 3M Dave Berquist (writing the C code) and myself (writing 
the lisp code) have collaborated to create a special window for displaying
debug messages from C routines called from LISP.  A special window
would not have been necessary and the code below can be easily adapted
to print to the listener if you want.  We defined a lisp function that was
callable from C to display arbitrary strings.  The C code calls
sprintf (rather than printf) to print to a string and then calls the function
passed from lisp to actually print it to a window.  You need to do a
one-time call to C to tell the C code what lisp function to call.  Your
conversion would amount to changing all the printf's to sprintf's and then
adding a call to the lisp function to print.  An example call to lisp is 
given at the end of the code below.  If you have any questions you can
send me a message directly.  Note that the code below is extracted from
a large body of code and we haven't tested it in isolation, but we believe
everything is there.   Paul Krueger (plkrueger@3m.com)

;;;
--------------------------------------------------------------------------------------
;;; sb-debug-set (lisp-func)                                                  -
function -
;;;
;;; Starts up a C debug function.
;;;
;;; Args: 
;;;   lisp-func is a pointer to a c-callable lisp function that accepts a
pointer to a
;;;     C string and prints the string into a debug window.
;;;
;;; Side Effects: None
;;;
;;; Return Value: None
;;;

(deffcfun (sb-debug-set "SB_debug_set")
  ((t :ptr)) :novalue)

;;;
--------------------------------------------------------------------------------------
;;; *debug-window*

(defobject *debug-window* *fred-window*)

(defobfun (exist *debug-window*) (init-list)
  (usual-exist (init-list-default init-list
                                  :window-title "C Debug Output"
                                  :window-position #@(406 50)
                                  :window-size #@(230 185))))

(defobfun (window-close *debug-window*) ()
  (setq *c-debug-window* nil)
  (usual-window-close))

;;;
--------------------------------------------------------------------------------------
;;; debug-set ()                                                              -
function -
;;;
;;; Starts up a C debug function.  Establishes a debug window
;;; and defines a lisp function to be called by C functions to print into it.
;;;
;;; Args: 
;;;   lisp-func is a pointer to a c-callable lisp function that accepts a
pointer to a
;;;     C string and prints the string into a debug window.
;;;
;;; Side Effects: Creates a debug window and a function called c-debug-print
that is
;;;               called from C.
;;;
;;; Return Value: nil
;;;

(defun debug-set ()
  (setq *c-debug-window* (oneof *debug-window*))
  (defccallable c-debug-print ((c-string :ptr) (:result :void))
    (if (null *c-debug-window*)
      (setq *c-debug-window* (oneof *debug-window*)))
    (do* ((str-offset 0 (incf str-offset))
          (next-char (code-char (%get-byte c-string str-offset))
                     (code-char (%get-byte c-string str-offset))))
         ((char= next-char #\null))
      (write-char next-char *c-debug-window*))
    (force-output *c-debug-window*)
    (ask *c-debug-window* 
      (set-mark 
       (window-start-mark)
       (buffer-line-start (window-buffer) (buffer-mark (window-buffer)) -12)))
    (ask *c-debug-window* (window-update)))
  (sb-debug-set c-debug-print))

;;;;;;;;;;;;;;;;;;;;   And on the C Side:

#define ADEBUG(y) if (SB_debug_fnptrG != 0L) (*SB_debug_fnptrG) (y)

 /* globals */
char SB_debug_arrayG[256];  /* buffer for printing into */
void (*SB_debug_fnptrG) ();



long debug_set (void (*funct_ptr) ())

/**************************************************************************
PURPOSE:

Initializes 'C' code to call a (LISP) function for "printf" like statements.

INPUTS:

funct_ptr - Pointer to funct to call when printing debug statements.  This
            function should take a char * as input and return void.

OUTPUTS:

Returns 0L.

SOURCE:

Dave Berquist, 3M Company

***************************************************************************/
{

 /* setup for debug print statements */
SB_debug_fnptrG = funct_ptr; /* pointer to LISP funct */

return(0L);
}



/*******************************************************************/
/* Example for using LISP function as a kind of stdout.            */
/* (translate a printf into this)                                  */
/* This example assumes that the LISP function given by            */
/* SB_debug_fnptrG takes a 'C' string as input and returns nothing */
/*******************************************************************/

sprintf(SB_debug_arrayG,"values: %d %d %d %d\n", a, b, c, d);
ADEBUG(SB_debug_arrayG);