[cffi-devel] varargs (again)

Hi, I saw some topics in the archives about varargs, but none answered how I might do this: ------------ xmlParserError (void *ctx, const char *msg, ...); ------------ SWIG (CFFI) produced this: ------------ (defcfun ("xmlParserError" xmlParserError) :void (ctx :pointer) (msg :string) (arg2 )) ------------ Is there any way I could use &rest here? or one big pointer? I don't quite know how to proceed... Cheers, Brad

Brad Anderson <brad@sankaty.com> writes:
(defcfun ("xmlParserError" xmlParserError) :void (ctx :pointer) (msg :string) (arg2 ))
This is obviously broken.
Is there any way I could use &rest here? or one big pointer? I don't quite know how to proceed...
Right now, you'll have to use foreign-funcall to use this function but I suppose we could come up with some sort of mechanism to define vararg functions. * (defcfun-varargs "printf" :int (control :string)) PRINTF * (printf (format nil "hello variadic %s! %d~%") :string "world" :int 42) hello variadic world! 42 25 What do you think of an interface like this? Possibly something like this would be better? (defcfun-varargs "printf" :int (constrol :string) (&rest args)) Also, maybe defcfun* would be a better name? Or even make defcfun recognize the (&rest ...) token? Here's a first try at this possible interface, in case you want to play with it: (in-package :cffi) (defmacro defcfun-varargs (name return-type &body args) "Defines a Lisp macro that expands into a foreign-funcall calling a varargs foreign function." (discard-docstring args) (with-unique-names (varargs) (let ((lisp-name (lisp-function-name name)) (foreign-name (foreign-function-name name)) (arg-names (mapcar #'car args))) `(defmacro ,lisp-name (,@arg-names &rest ,varargs) `(foreign-funcall ,',foreign-name ,@,`(list ,@(loop for pair in args collect (second pair) collect (first pair))) ,@,varargs ,',return-type))))) Using this macro you would do something like this: (defcfun-varargs ("xmlParserError" xml-parser-error) :void (ctx :pointer) (msg :string)) (xml-parser-error some-ctx "error number: %d" 42) But, this is a bad example. In this case, I suppose what you really should do is probably something like this: (defcfun "xmlParserError" :void (ctx :pointer) (msg :string)) (defun xml-parser-error (control-string &rest args) (xmlParserError <whatever-a-ctx-is> (format nil "~?" control-string args))) (xml-parser-error "error number: ~A" 42) Does anyone have an example where some sort of defcfun-varargs could actually be useful? -- Luís Oliveira luismbo (@) gmail (.) com Equipa Portuguesa do Translation Project http://www.iro.umontreal.ca/translation/registry.cgi?team=pt

Luís Oliveira <luismbo@gmail.com> writes:
Does anyone have an example where some sort of defcfun-varargs could actually be useful?
This could be useful for the Objective-C bridge: ;; Just tossing out ideas about syntax here... (defcfun ("objc_msgSend" send) id (object id) (method selector) &rest) (send (find-objc-class "NSString") "stringWithUTF8String:" (:string :encoding :utf-8) "hi") I think this could be pretty cool (modulo the arguments *rimshot* about the portability of calling varargs functions through FFI, of course..) James
participants (3)
-
Brad Anderson
-
James Bielman
-
Luís Oliveira