Frank Goenninger <fgoenninger@prion.de> writes:
Thanks for looking into this ... I want to call the functions Tcl_CreateInterp and Tcl_Eval from Lisp. So I defined the libs and the functions :
[ snippage ]
;; Tcl_EvalFile
(defcfun ("Tcl_EvalFile" %Tcl_EvalFile) :int (interp :pointer) (filename-cstr :pointer))
(defun Tcl_EvalFile (interp filename) (with-foreign-pointer (filename-cstr (length filename) strlen) (setf (mem-ref filename-cstr :char (1- strlen)) 0) (lisp-string-to-foreign filename filename-cstr strlen) %Tcl_EvalFile interp filename-cstr))
;; Tcl_Eval
(defcfun ("Tcl_Eval" %Tcl_Eval) :int (interp :pointer) (script-cstr :pointer))
(defun Tcl_Eval (interp script) (with-foreign-pointer (script-cstr (length script) strlen) (setf (mem-ref script-cstr :char (1- strlen)) 0) (lisp-string-to-foreign script script-cstr strlen) %Tcl_Eval interp script-cstr))
You seem to be going to a fair bit of trouble here to reproduce what the CFFI :STRING type does automatically... why not something like: (defcfun ("Tcl_EvalFile" tcl-eval-file) :int (interp :pointer) (filename :string)) (defcfun ("Tcl_Eval" tcl-eval) :int (interp :pointer) (script :string)) instead of mucking about with low-level stuff like null terminators. There is also WITH-FOREIGN-STRING that encapsulates this pattern in a macro when you don't want to use the :STRING type. Also, one technique I've found very handy when writing bindings for APIs that are consistent about returning error codes is to define a special result type and hang a translator on it, to get automatic error checking (untested, caveat executor): ;; Now TCL-EVAL-FILE and TCL-EVAL can return a TCL-ERROR instead of ;; :INT and the translator will get called on the return value. (defctype tcl-error :int) (defmethod translate-from-foreign (value (type (eql 'tcl-error))) (unless (zerop value) ;; or whatever (error "got some tcl error ~D..." value)) value) Apart from any other TCL-specific issues like Yaroslav mentioned, perhaps the TCL output stream is buffered and needs to be flushed somehow? James