[Openmcl-devel] def-foreign-type problem

John DeSoi jdesoi at planetc.com
Sun Sep 22 14:28:03 PDT 2002


Hi Gary,

At 11:46 PM -0600 9/21/02, Gary Byers wrote:
>That's as expected (and is equivalent to what you'd get if you compiled:
>
>struct {
>   short f1;
>   long f2;
>};
>
>in C (under default alignment rules.)  It's also equivalent to:
>
>(ccl::def-foreign-type nil
>                   (:struct tst-with-explicit-padding
>                      (:f1 :short)
>                      (:pad :short) ; ensure 32-bit alignment of the following
>                      (:f2 :long)))

I thought it might be something like this, but I also tested making a 
struct with 3 short values. The size of that is 6 bytes. Why not 8 
here, or is padding not an issue at the end of the structure?

>
>Out of curiosity, did you ask about this because you have some C code
>that assumes 16-bit alignment, or were you just curious ?  (I'd sort
>of convinced myself that there was no need to handle 16-bit alignment
>in DEF-FOREIGN-TYPE, since that would only exist in a few old Apple
>header files that the interface translator should process ...)
>

Yes, I have run into this as a possible problem in trying to solve 
the issue of getting a FSSpec to pass to a foreign library. With the 
pointers you gave me, I discovered the entry points FSPathMakeRef and 
FSGetCatalogInfo which turns a FSRef into a FSSpec (both were 
accessible without opening the core foundation library). I can call 
both routines without error, but the library fails to open or create 
the file. In looking at the name field of the FSSpec, it (finally) 
became obvious to me that it was off by 2 bytes. So if I want to read 
or write data from FSSpec struct, I need to load it's definition with 
(use-interface-dir :carbon) rather than defining it myself?

FYI, below is what I have so far (specified in UFFI; I have included 
some of the macroexpansions also).


Thanks again for all your help,

John DeSoi, Ph.D.

=====

(uffi:def-struct fsspec
    (vRefNum :short)
    (parID :long)
    (name (:array :unsigned-byte 256))) ;64 prior to os x

(uffi:def-foreign-type :fsspecptr (* :fsspec))

(uffi:def-struct fsref
    (hidden (:array :unsigned-byte 80))) ;contents are completely opaque

(uffi:def-foreign-type :fsrefptr (* :fsref))


(uffi:def-function ("FSPathMakeRef" FSPathMakeRef)
                    ((path (* :unsigned-byte))
                     (ref :fsrefptr)
                     (is-directory :byte))
                    :returning :long)

(uffi:def-function ("FSGetCatalogInfo" FSGetCatalogInfo)
                    ((ref :fsrefptr)
                     (which-info :unsigned-long) ;see Files.h for this
                     (catalog-info *)
                     (outname *)
                     (fsspec :fsspecptr)
                     (parentRef :fsrefptr))
                    :returning :long)

; with-foreign-objects expands to %stack-block
(defmacro with-file-spec ((fspec path) &body body)
   `(if (check-directory ,path)
      (let ((nullptr (uffi:make-null-pointer :unsigned-long)))
        (uffi:with-cstring (path-str (namestring 
(translate-logical-pathname ,path)))
          (uffi:with-foreign-objects ((,fspec :fsspec) (fref :fsref))
            (FSPathMakeRef path-str fref 0)
            (FSGetCatalogInfo fref 0 nullptr nullptr ,fspec nullptr)
            , at body)))))



Expansions for FSSpec and the two function calls (some extraneous 
stuff removed):

(CCL::%DEF-AUXILIARY-FOREIGN-TYPES
'((:STRUCT FSSPEC
    #<FOREIGN-RECORD-TYPE (CCL::STRUCT FSSPEC (VREFNUM (CCL::SIGNED 16))
						  (PARID (CCL::SIGNED 32))
						  (NAME
						   (ARRAY 
(CCL::UNSIGNED 8) 256))) #x52DB67E>)))
                               
                               
                               
(CCL::%DEFUN (NFUNCTION FSPATHMAKEREF
                                (LAMBDA (PATH REF IS-DIRECTORY)
                                  (DECLARE (CCL::GLOBAL-FUNCTION-NAME
                                            FSPATHMAKEREF))
                                  (BLOCK FSPATHMAKEREF
                                    (CCL::EXTERNAL-CALL
                                      "_FSPathMakeRef"
                                      :ADDRESS
                                      PATH
                                      :FSREFPTR
                                      REF
                                      :SIGNED-BYTE
                                      IS-DIRECTORY
                                      :LONG))))
                     'NIL)
                    


(CCL::%DEFUN (NFUNCTION FSGETCATALOGINFO
                                (LAMBDA (REF
                                         WHICH-INFO
                                         CATALOG-INFO
                                         OUTNAME
                                         FSSPEC
                                         PARENTREF)
                                  (DECLARE (CCL::GLOBAL-FUNCTION-NAME
                                            FSGETCATALOGINFO))
                                  (BLOCK FSGETCATALOGINFO
                                    (CCL::EXTERNAL-CALL
                                      "_FSGetCatalogInfo"
                                      :FSREFPTR
                                      REF
                                      :UNSIGNED-LONG
                                      WHICH-INFO
                                      :ADDRESS
                                      CATALOG-INFO
                                      :ADDRESS
                                      OUTNAME
                                      :FSSPECPTR
                                      FSSPEC
                                      :FSREFPTR
                                      PARENTREF
                                      :LONG))))
                     'NIL)

_______________________________________________
Openmcl-devel mailing list
Openmcl-devel at clozure.com
http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel




More information about the Openmcl-devel mailing list