[Openmcl-devel] foreign fn call

Gary Byers gb at clozure.com
Mon Mar 29 03:18:08 UTC 2010



On Sun, 28 Mar 2010, Philippe Sismondi wrote:

> I have taken a month or two away from CL to learn obj-c/cocoa so that I can
> use the cocoa bridge more knowledgeably. Now I am reading up on foreign
> functions etc. in the ccl documentation.
> 
> Question:
> 
> The ccl doc section 12.12 The Foreign-Function-Interface Dictionary gives
> this example:
> 
> (with-cstrs ((format-string "the answer is: %d"))
>           (#_printf format-string :int answer))
> 
> This just returns an integer (19) when I key it in to ccl. Should I expect
> it to print what it looks like it would print? What else must I do here? (I
> had set 'answer' to an integer value.)
>

The C function "printf" writes to a C "FILE *" associated with the process's
standard output.  Where is that, exactly ?

If you're running in a terminal window, that's likely the terminal window.
If you're running in an Emacs shell buffer, that's likely that shell buffer.
If you're running under SLIME, that's likely the "inferior lisp" buffer
  (or whatever it's called.)
If you're running under the CCL IDE, that's likely a logging device of some
  sort.
There may be other possibilities, but in general "the process's standard output
  device" and "what the REPL thread uses for *STANDARD-OUTPUT*" may or may not
  be the same thing.

I don't know how you're running the lisp, so I don't know where (if
anywhere) printf's output went.  As your later message notes, it's
possible that that output is still buffered, and to ensure that that
output is visible (somewhere) it's necessary to do

? (#_fflush stdout)

That's pretty simple; the problem is that "stdout" is often a preprocessor
macro that expands into something that often looks like line noise.  Whatever
that expansion is, it tends to be platform-dependent; on OSX, it changed between
10.4 and 10.5 (though the old mechanism may still be used in code that needs
to run on 10.4).  CCL 1.4 still runs under 10.4; the trunk (and next release)
won't.

Here's a function that tries to return a pointer to C's "stdout" stream; it
makes use of the #& reader macro (which is used to access foreign variables)
and of the fact that #&?name can be used to determine whether a foreign variable
named "name" is defined.

(defun c-stdout ()
   #+linux  #&stdout          ; actually sane
   #+darwin (if #&?__stdoutp #&__stdoutp #&__sF)  ; somewhat less sane
   #-(or linux darwin) (error "left as an exercise"))

(#_fflush (c-stdout))

The #_printf example was supposed to illustrate how to call foreign
functions that take variable numbers of args; it wasn't supposed to
expose the fact that C stdio tends to be a rat's nest ...




> - phil -
> 
>


More information about the Openmcl-devel mailing list