This is using the latest darcs cffi on SBCL 0.9.5 ...
I have a list of lists of strings and have created the translations below (the arrays end up null-terminated):
(defctype string-list :pointer) (defctype string-lists :pointer)
(defmethod translate-to-foreign (value (type (eql 'string-list))) (let ((foreign (foreign-alloc :string :initial-contents value :count (1+ (length value))))) (setf (mem-aref foreign :pointer (length value)) (null-pointer)) foreign))
(defmethod translate-to-foreign (value (type (eql 'string-lists))) (let ((foreign (foreign-alloc 'string-list :initial-contents value :count (1+ (length value))))) (setf (mem-aref foreign :pointer (length value)) (null-pointer)) foreign))
I get an error on the call to t-t-f for string-list, because the value is a pointer and not a sequence. If I change the foreign-alloc type to :pointer instead of string-list, it compalains that ("foo" "bar") is not a pointer (which makes sense).
So, using 'string-list seems to try to double-convert (which I don't expect), :pointer seems to not convert at all (which I do expect). So, any idea what I'm doing wrong?
Here's the error:
0: (LENGTH #.(SB-SYS:INT-SAP #X082CCA70)) 1: ((SB-PCL::FAST-METHOD CFFI:TRANSLATE-TO-FOREIGN (T (EQL (QUOTE PRODUCT-DISC OVERY::STRING-LIST)))) #<unavailable argument> #<unavailable argument> #.(SB-SYS :INT-SAP #X082CCA70) #<unavailable argument>) 2: ((SB-PCL::FAST-METHOD CFFI::TRANSLATE-TYPE-TO-FOREIGN (T CFFI::FOREIGN-TYPE DEF)) #<unavailable argument> #<unavailable argument> #.(SB-SYS:INT-SAP #X082CCA 70) #<CFFI::FOREIGN-TYPEDEF PRODUCT-DISCOVERY::STRING-LIST>) 3: (CFFI::MEM-SET #.(SB-SYS:INT-SAP #X082CCA70) #.(SB-SYS:INT-SAP #X082CD488) PRODUCT-DISCOVERY::STRING-LIST 0) 4: (CFFI:FOREIGN-ALLOC PRODUCT-DISCOVERY::STRING-LIST :INITIAL-ELEMENT NIL :IN ITIAL-CONTENTS (("ASIN" "B0002E3MRW")) :COUNT 2) 5: ((SB-PCL::FAST-METHOD CFFI:TRANSLATE-TO-FOREIGN (T (EQL (QUOTE PRODUCT-DISC OVERY::STRING-LISTS)))) #<unavailable argument> #<unavailable argument> (("ASIN" "B0002E3MRW")) #<unavailable argument>) 6: ((SB-PCL::FAST-METHOD CFFI::TRANSLATE-TYPE-TO-FOREIGN (T CFFI::FOREIGN-TYPE DEF)) #<unavailable argument> #<unavailable argument> (("ASIN" "B0002E3MRW")) #< CFFI::FOREIGN-TYPEDEF PRODUCT-DISCOVERY::STRING-LISTS>)
If I change the foreign-alloc to this, things seem to be alright:
(foreign-alloc :pointer :initial-contents (mapcar (lambda (list) (translate-to-foreign list
'string-list)) value) :count (1+ (length value)))
Here I'm manually doing the nested translation, but I would have figured this was done for me just fine.
On Feb 23, 2006, at 4:36 PM, Greg Pfeil wrote:
This is using the latest darcs cffi on SBCL 0.9.5 ...
I have a list of lists of strings and have created the translations below (the arrays end up null-terminated):
(defctype string-list :pointer) (defctype string-lists :pointer)
(defmethod translate-to-foreign (value (type (eql 'string-list))) (let ((foreign (foreign-alloc :string :initial-contents value :count (1+ (length value))))) (setf (mem-aref foreign :pointer (length value)) (null-pointer)) foreign))
(defmethod translate-to-foreign (value (type (eql 'string-lists))) (let ((foreign (foreign-alloc 'string-list :initial-contents value :count (1+ (length value))))) (setf (mem-aref foreign :pointer (length value)) (null-pointer)) foreign))
I get an error on the call to t-t-f for string-list, because the value is a pointer and not a sequence. If I change the foreign-alloc type to :pointer instead of string-list, it compalains that ("foo" "bar") is not a pointer (which makes sense).
So, using 'string-list seems to try to double-convert (which I don't expect), :pointer seems to not convert at all (which I do expect). So, any idea what I'm doing wrong?
Here's the error:
0: (LENGTH #.(SB-SYS:INT-SAP #X082CCA70)) 1: ((SB-PCL::FAST-METHOD CFFI:TRANSLATE-TO-FOREIGN (T (EQL (QUOTE PRODUCT-DISC OVERY::STRING-LIST)))) #<unavailable argument> #<unavailable argument> #.(SB-SYS :INT-SAP #X082CCA70) #<unavailable argument>) 2: ((SB-PCL::FAST-METHOD CFFI::TRANSLATE-TYPE-TO-FOREIGN (T CFFI::FOREIGN-TYPE DEF)) #<unavailable argument> #<unavailable argument> #.(SB-SYS:INT-SAP #X082CCA 70) #<CFFI::FOREIGN-TYPEDEF PRODUCT-DISCOVERY::STRING-LIST>) 3: (CFFI::MEM-SET #.(SB-SYS:INT-SAP #X082CCA70) #.(SB-SYS:INT-SAP #X082CD488) PRODUCT-DISCOVERY::STRING-LIST 0) 4: (CFFI:FOREIGN-ALLOC PRODUCT-DISCOVERY::STRING-LIST :INITIAL-ELEMENT NIL :IN ITIAL-CONTENTS (("ASIN" "B0002E3MRW")) :COUNT 2) 5: ((SB-PCL::FAST-METHOD CFFI:TRANSLATE-TO-FOREIGN (T (EQL (QUOTE PRODUCT-DISC OVERY::STRING-LISTS)))) #<unavailable argument> #<unavailable argument> (("ASIN" "B0002E3MRW")) #<unavailable argument>) 6: ((SB-PCL::FAST-METHOD CFFI::TRANSLATE-TYPE-TO-FOREIGN (T CFFI::FOREIGN-TYPE DEF)) #<unavailable argument> #<unavailable argument> (("ASIN" "B0002E3MRW")) #< CFFI::FOREIGN-TYPEDEF PRODUCT-DISCOVERY::STRING-LISTS>)
cffi-devel mailing list cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
On 2006-feb-24, at 00:36, Greg Pfeil wrote:
So, using 'string-list seems to try to double-convert (which I don't expect),
Thanks for the bug report. Should be fixed now. Added a :NULL- TERMINATED-P option too like we discussed on IRC.