For functions using the libffi foreign-funcall path, functions defined with :string parameters still fail because TRANSLATE-INTO-FOREIGN-MEMORY is not defined on FOREIGN-STRING-TYPE. E.g.,
(defcfun ("xcb_intern_atom" xcb-intern-atom) (:struct xcb-intern-atom-cookie-t) (c :pointer) (only_if_exists :unsigned-char) (name_len :unsigned-short) (name :string))
Calling this fails:
There is no applicable method for the generic function #<STANDARD-GENERIC-FUNCTION TRANSLATE-INTO-FOREIGN-MEMORY (5)> when called with arguments (#.(SB-SYS:INT-SAP #X7FFFD8000DC0) #<CFFI::FOREIGN-STRING-TYPE :UTF-8> #.(SB-SYS:INT-SAP #X7FFFECDB7FD8)). [Condition of type SIMPLE-ERROR]
This is using unmodified master.
Please pull and check Head: 399f51a896 - New method #'translate-into-foreign-memory for foreign-string-type
Liam
On Fri, May 18, 2012 at 1:19 PM, Ryan Pavlik rpavlik@gmail.com wrote:
For functions using the libffi foreign-funcall path, functions defined with :string parameters still fail because TRANSLATE-INTO-FOREIGN-MEMORY is not defined on FOREIGN-STRING-TYPE. E.g.,
(defcfun ("xcb_intern_atom" xcb-intern-atom) (:struct xcb-intern-atom-cookie-t) (c :pointer) (only_if_exists :unsigned-char) (name_len :unsigned-short) (name :string))
Calling this fails:
There is no applicable method for the generic function #<STANDARD-GENERIC-FUNCTION TRANSLATE-INTO-FOREIGN-MEMORY (5)> when called with arguments (#.(SB-SYS:INT-SAP #X7FFFD8000DC0) #<CFFI::FOREIGN-STRING-TYPE :UTF-8> #.(SB-SYS:INT-SAP #X7FFFECDB7FD8)). [Condition of type SIMPLE-ERROR]
This is using unmodified master.
-- Ryan Pavlik rpavlik@gmail.com 425.220.9585
cffi-devel mailing list cffi-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
On Sat, May 26, 2012 at 11:15 PM, Liam Healy lnp@healy.washington.dc.us wrote:
Please pull and check Head: 399f51a896 - New method #'translate-into-foreign-memory for foreign-string-type
Did you notice the function lisp-string-to-foreign? Seems like a cleaner way to implement translate-into-foreign-memory.
On Sun, May 27, 2012 at 9:15 PM, Luís Oliveira luismbo@gmail.com wrote:
Did you notice the function lisp-string-to-foreign? Seems like a cleaner way to implement translate-into-foreign-memory.
More importantly, how can you be translating a string without performing allocation in this case? Also, in general, translate-into-foreign-memory for strings should definitely refuse to accept string types without an explicit size. (Which is not implemented yet, IIRC.)
In any case, why does Ryan's example need translate-into-foreign-memory?
On Sun, May 27, 2012 at 4:48 PM, Luís Oliveira luismbo@gmail.com wrote:
On Sun, May 27, 2012 at 9:15 PM, Luís Oliveira luismbo@gmail.com wrote:
Did you notice the function lisp-string-to-foreign? Seems like a cleaner way to implement translate-into-foreign-memory.
More importantly, how can you be translating a string without performing allocation in this case? Also, in general, translate-into-foreign-memory for strings should definitely refuse to accept string types without an explicit size. (Which is not implemented yet, IIRC.)
In any case, why does Ryan's example need translate-into-foreign-memory?
Yeah, the new method is the wrong thing, I need to revert this change. When foreign-funcall-form is called and fsbvp=T, it calls translate-objects with indirect=T, which in turn calls #'expand-to-foreign-dyn-indirect on each of the arguments. When an argument is a foreign-string-type, the trouble begins. The foreign string is represented by a pointer, as indicated by the (:actual-type :pointer) in the define-foreign-type. All libffi really needs is a pointer to the pointer, and there is a method for expand-to-foreign-dyn-indirect for foreign-pointer-type, but foreign-string-type is not a subclass of foreign-pointer-type.
It seems like the resolution is to define a method for expand-to-foreign-dyn-indirect for the foreign-type-alias class that does a recursive call using the actual-type. Does that make sense? As a side point, expand-to-foreign-dyn has a similar method but it is defined for enhanced-typedef (subclass chain: enhanced-typedef < foreign-typedef < foreign-type-alias); is there any reason why that method shouldn't be defined for foreign-type-alias instead?
Liam
OK, I've done this in master; there is a new method for foreign-type-alias in expand-to-foreign-dyn-indirect. Ryan, can you test this version, and, if possible, post a simple example (whether it worked or not) that we can add to cffi-tests. Thank you.
Liam
On Mon, May 28, 2012 at 11:33 PM, Liam Healy lnp@healy.washington.dc.uswrote:
On Sun, May 27, 2012 at 4:48 PM, Luís Oliveira luismbo@gmail.com wrote:
On Sun, May 27, 2012 at 9:15 PM, Luís Oliveira luismbo@gmail.com wrote:
Did you notice the function lisp-string-to-foreign? Seems like a cleaner way to implement translate-into-foreign-memory.
More importantly, how can you be translating a string without performing allocation in this case? Also, in general, translate-into-foreign-memory for strings should definitely refuse to accept string types without an explicit size. (Which is not implemented yet, IIRC.)
In any case, why does Ryan's example need translate-into-foreign-memory?
Yeah, the new method is the wrong thing, I need to revert this change. When foreign-funcall-form is called and fsbvp=T, it calls translate-objects with indirect=T, which in turn calls #'expand-to-foreign-dyn-indirect on each of the arguments. When an argument is a foreign-string-type, the trouble begins. The foreign string is represented by a pointer, as indicated by the (:actual-type :pointer) in the define-foreign-type. All libffi really needs is a pointer to the pointer, and there is a method for expand-to-foreign-dyn-indirect for foreign-pointer-type, but foreign-string-type is not a subclass of foreign-pointer-type.
It seems like the resolution is to define a method for expand-to-foreign-dyn-indirect for the foreign-type-alias class that does a recursive call using the actual-type. Does that make sense? As a side point, expand-to-foreign-dyn has a similar method but it is defined for enhanced-typedef (subclass chain: enhanced-typedef < foreign-typedef < foreign-type-alias); is there any reason why that method shouldn't be defined for foreign-type-alias instead?
Liam