[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