Lisp HUG Maillist Archive

A Mac OS X very specific question

Hi,

Some procedures on Mac OS X need always the old structure FSSpec (QuickTime
for instance). I have to transmit a pathname by this way to some coreAudio
MusicDevice. I found the way to get a FSSpec from a FSRef from a lisp
string... The pathname seems to be correctly transmitted to the foreign
routines : no error code and the file I want to load is correctly loaded.
But after several calls to the function (sometimes 1, sometimes more...) LW
crashes, often when quitting. It¹s impossible for me to understand if the
problem is in my codes, in the Mac codes or in the LW codes...

I tried to reproduce a very simple example here but, however, it¹s need some
lines of codes... I'm really sorry.

Any suggestion will be very appreciated !

Thanks

Denis



(defpackage "PACKAGE-FOO"
  (:nicknames foo) (:use cl fli))

(in-package :foo)


(define-c-typedef Uint8 (:unsigned :char))
(define-c-typedef Uint32 (:unsigned :long))


#|
declaration in Files.h :
struct FSRef {
  UInt8               hidden[80];             /* private to File Manager;
need symbolic constant */
};

typedef struct FSRef                    FSRef;
|#

(define-c-struct FSRef  (hidden (:c-array Uint8 80)))


#|
declaration  in Files.h :
struct FSSpec {
  short               vRefNum;
  long                parID;
  StrFileName         name;                   /* a Str63 on MacOS*/
};

typedef struct FSSpec                   FSSpec;
|#

(define-c-struct FSSpec
  (vRefNum :short)
  (parID :long)
  (StrFilename (:pointer (:c-array Uint8 64))))

#|
declaration  in Files.h :
extern OSStatus  FSPathMakeRef(const UInt8 *path, FSRef *ref, Boolean
*isDirectory)   
|#

(define-foreign-function (FSPathMakeRef "FSPathMakeRef") ((path
(:reference-pass (:ef-mb-string :limit 255 :null-terminated-p t))) (ref
(:pointer FSRef)) (isDirectory (:reference-return :boolean))) ;
  :result-type :long)

#|
declaration  in Files.h :
extern OSErr  FSGetCatalogInfo(const FSRef *ref, FSCatalogInfoBitmap
whichInfo, FSCatalogInfo *catalogInfo, HFSUniStr255 *outName, FSSpec
*fsSpec, FSRef *parentRef)
|#

(define-foreign-function (FSGetCatalogInfo "FSGetCatalogInfo") ((FSref
(:const (:ptr FSRef))) (whichInfo Uint32) (catalogInfo (:ptr :void))
(outName (:ptr :void)) (fsSpec (:ptr fsSpec)) (parentRef (:ptr :void))) ;
  :result-type :long)

;my function

(defmacro with-no-error (code &body body)
  `(let ((error (progn ,.body)))
     (unless (zerop error) (error (format nil "~d ~d" ,code error)))))

(defun string->FSSpec (string)
  (let ((FSRef (allocate-foreign-object :type 'FSRef))
        (FSSpec (allocate-foreign-object :type 'FSspec)))
    (with-no-error "FSPathMakeRef" (FSPathMakeRef string FSRef nil))
    (with-no-error "FSGetCatalogInfo" (FSGetCatalogInfo FSRef 0 nil nil
FSSpec nil))
    (free FSRef) ;I'm not sure about that, but it crashes anyway...
    (free FSSpec)))


#|

(dotimes (i 10) (string->FSSpec pathname-string)) ;<--- put here every
pathname to an existing file

normally the system crashes after evaluation (or when quitting LW)...
|#


-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@compositeurs.be
Website : http://compositeurs.be/pousseur
-------------------------------------------------------





Re: A Mac OS X very specific question

Don't quote me, but...

At a quick glance, your translation of the FSSpec type is wrong.   
You've defined the filename element as a pointer to a 64-byte array  
but the actual definition in the header file is that the filename  
element is the 64-byte array.  So, you're FSSpec structure isn't long  
enough and your causing your C heap to be corrupted.

Change the definition of FSSpec to

(define-c-struct FSSpec
   (vRefNum :short)
   (parID :long)
   (StrFilename (:c-array Uint8 64)))

and see what happens.

   - Gary Palter
     Principal Software Engineer
     Clozure Associates
     Cell:  617-947-0536


On Oct 27, 2006, at 3:14 PM, Denis Pousseur wrote:

>
> Hi,
>
> Some procedures on Mac OS X need always the old structure FSSpec  
> (QuickTime
> for instance). I have to transmit a pathname by this way to some  
> coreAudio
> MusicDevice. I found the way to get a FSSpec from a FSRef from a lisp
> string... The pathname seems to be correctly transmitted to the  
> foreign
> routines : no error code and the file I want to load is correctly  
> loaded.
> But after several calls to the function (sometimes 1, sometimes  
> more...) LW
> crashes, often when quitting. It’s impossible for me to understand  
> if the
> problem is in my codes, in the Mac codes or in the LW codes...
>
> I tried to reproduce a very simple example here but, however, it’s  
> need some
> lines of codes... I'm really sorry.
>
> Any suggestion will be very appreciated !
>
> Thanks
>
> Denis
>
>
>
> (defpackage "PACKAGE-FOO"
>   (:nicknames foo) (:use cl fli))
>
> (in-package :foo)
>
>
> (define-c-typedef Uint8 (:unsigned :char))
> (define-c-typedef Uint32 (:unsigned :long))
>
>
> #|
> declaration in Files.h :
> struct FSRef {
>   UInt8               hidden[80];             /* private to File  
> Manager;
> need symbolic constant */
> };
>
> typedef struct FSRef                    FSRef;
> |#
>
> (define-c-struct FSRef  (hidden (:c-array Uint8 80)))
>
>
> #|
> declaration  in Files.h :
> struct FSSpec {
>   short               vRefNum;
>   long                parID;
>   StrFileName         name;                   /* a Str63 on MacOS*/
> };
>
> typedef struct FSSpec                   FSSpec;
> |#
>
> (define-c-struct FSSpec
>   (vRefNum :short)
>   (parID :long)
>   (StrFilename (:pointer (:c-array Uint8 64))))
>
> #|
> declaration  in Files.h :
> extern OSStatus  FSPathMakeRef(const UInt8 *path, FSRef *ref, Boolean
> *isDirectory)
> |#
>
> (define-foreign-function (FSPathMakeRef "FSPathMakeRef") ((path
> (:reference-pass (:ef-mb-string :limit 255 :null-terminated-p t)))  
> (ref
> (:pointer FSRef)) (isDirectory (:reference-return :boolean))) ;
>   :result-type :long)
>
> #|
> declaration  in Files.h :
> extern OSErr  FSGetCatalogInfo(const FSRef *ref, FSCatalogInfoBitmap
> whichInfo, FSCatalogInfo *catalogInfo, HFSUniStr255 *outName, FSSpec
> *fsSpec, FSRef *parentRef)
> |#
>
> (define-foreign-function (FSGetCatalogInfo "FSGetCatalogInfo") ((FSref
> (:const (:ptr FSRef))) (whichInfo Uint32) (catalogInfo (:ptr :void))
> (outName (:ptr :void)) (fsSpec (:ptr fsSpec)) (parentRef  
> (:ptr :void))) ;
>   :result-type :long)
>
> ;my function
>
> (defmacro with-no-error (code &body body)
>   `(let ((error (progn ,.body)))
>      (unless (zerop error) (error (format nil "~d ~d" ,code error)))))
>
> (defun string->FSSpec (string)
>   (let ((FSRef (allocate-foreign-object :type 'FSRef))
>         (FSSpec (allocate-foreign-object :type 'FSspec)))
>     (with-no-error "FSPathMakeRef" (FSPathMakeRef string FSRef nil))
>     (with-no-error "FSGetCatalogInfo" (FSGetCatalogInfo FSRef 0 nil  
> nil
> FSSpec nil))
>     (free FSRef) ;I'm not sure about that, but it crashes anyway...
>     (free FSSpec)))
>
>
> #|
>
> (dotimes (i 10) (string->FSSpec pathname-string)) ;<--- put here every
> pathname to an existing file
>
> normally the system crashes after evaluation (or when quitting LW)...
> |#
>
>
> -------------------------------------------------------
> Denis Pousseur
> 70 rue de Wansijn
> 1180 Bruxelles, Belgique
>
> Tel : 32 (0)2 219 31 09
> Mail :  denis.pousseur@compositeurs.be
> Website : http://compositeurs.be/pousseur
> -------------------------------------------------------
>
>
>



Re: A Mac OS X very specific question

Gosh ! I'm to stupid ! It works perfectly now...
Your "quick glance" is more accurate than a few ours of mine...

Thanks a lot !

Denis

PS : if I can abuse of your knowledge...: must a foreign structure define in
lisp be deallocated, even if the foreign procedure doesn't require an
explicit release ? (the FSSpec and the FSREF structures don't need release
as I can read in the Mac doc. However, I free the foreign structure in my
code. Is it correct ?).


Le 27/10/06 21:27, « [NOM] » <[ADRESSE]> a écrit :

> 
> Don't quote me, but...
> 
> At a quick glance, your translation of the FSSpec type is wrong.
> You've defined the filename element as a pointer to a 64-byte array
> but the actual definition in the header file is that the filename
> element is the 64-byte array.  So, you're FSSpec structure isn't long
> enough and your causing your C heap to be corrupted.
> 
> Change the definition of FSSpec to
> 
> (define-c-struct FSSpec
>    (vRefNum :short)
>    (parID :long)
>    (StrFilename (:c-array Uint8 64)))
> 
> and see what happens.
> 
>    - Gary Palter
>      Principal Software Engineer
>      Clozure Associates
>      Cell:  617-947-0536
> 
> 
> On Oct 27, 2006, at 3:14 PM, Denis Pousseur wrote:
> 
>> 
>> Hi,
>> 
>> Some procedures on Mac OS X need always the old structure FSSpec
>> (QuickTime
>> for instance). I have to transmit a pathname by this way to some
>> coreAudio
>> MusicDevice. I found the way to get a FSSpec from a FSRef from a lisp
>> string... The pathname seems to be correctly transmitted to the
>> foreign
>> routines : no error code and the file I want to load is correctly
>> loaded.
>> But after several calls to the function (sometimes 1, sometimes
>> more...) LW
>> crashes, often when quitting. It¹s impossible for me to understand
>> if the
>> problem is in my codes, in the Mac codes or in the LW codes...
>> 
>> I tried to reproduce a very simple example here but, however, it¹s
>> need some
>> lines of codes... I'm really sorry.
>> 
>> Any suggestion will be very appreciated !
>> 
>> Thanks
>> 
>> Denis
>> 
>> 
>> 
>> (defpackage "PACKAGE-FOO"
>>   (:nicknames foo) (:use cl fli))
>> 
>> (in-package :foo)
>> 
>> 
>> (define-c-typedef Uint8 (:unsigned :char))
>> (define-c-typedef Uint32 (:unsigned :long))
>> 
>> 
>> #|
>> declaration in Files.h :
>> struct FSRef {
>>   UInt8               hidden[80];             /* private to File
>> Manager;
>> need symbolic constant */
>> };
>> 
>> typedef struct FSRef                    FSRef;
>> |#
>> 
>> (define-c-struct FSRef  (hidden (:c-array Uint8 80)))
>> 
>> 
>> #|
>> declaration  in Files.h :
>> struct FSSpec {
>>   short               vRefNum;
>>   long                parID;
>>   StrFileName         name;                   /* a Str63 on MacOS*/
>> };
>> 
>> typedef struct FSSpec                   FSSpec;
>> |#
>> 
>> (define-c-struct FSSpec
>>   (vRefNum :short)
>>   (parID :long)
>>   (StrFilename (:pointer (:c-array Uint8 64))))
>> 
>> #|
>> declaration  in Files.h :
>> extern OSStatus  FSPathMakeRef(const UInt8 *path, FSRef *ref, Boolean
>> *isDirectory)
>> |#
>> 
>> (define-foreign-function (FSPathMakeRef "FSPathMakeRef") ((path
>> (:reference-pass (:ef-mb-string :limit 255 :null-terminated-p t)))
>> (ref
>> (:pointer FSRef)) (isDirectory (:reference-return :boolean))) ;
>>   :result-type :long)
>> 
>> #|
>> declaration  in Files.h :
>> extern OSErr  FSGetCatalogInfo(const FSRef *ref, FSCatalogInfoBitmap
>> whichInfo, FSCatalogInfo *catalogInfo, HFSUniStr255 *outName, FSSpec
>> *fsSpec, FSRef *parentRef)
>> |#
>> 
>> (define-foreign-function (FSGetCatalogInfo "FSGetCatalogInfo") ((FSref
>> (:const (:ptr FSRef))) (whichInfo Uint32) (catalogInfo (:ptr :void))
>> (outName (:ptr :void)) (fsSpec (:ptr fsSpec)) (parentRef
>> (:ptr :void))) ;
>>   :result-type :long)
>> 
>> ;my function
>> 
>> (defmacro with-no-error (code &body body)
>>   `(let ((error (progn ,.body)))
>>      (unless (zerop error) (error (format nil "~d ~d" ,code error)))))
>> 
>> (defun string->FSSpec (string)
>>   (let ((FSRef (allocate-foreign-object :type 'FSRef))
>>         (FSSpec (allocate-foreign-object :type 'FSspec)))
>>     (with-no-error "FSPathMakeRef" (FSPathMakeRef string FSRef nil))
>>     (with-no-error "FSGetCatalogInfo" (FSGetCatalogInfo FSRef 0 nil
>> nil
>> FSSpec nil))
>>     (free FSRef) ;I'm not sure about that, but it crashes anyway...
>>     (free FSSpec)))
>> 
>> 
>> #|
>> 
>> (dotimes (i 10) (string->FSSpec pathname-string)) ;<--- put here every
>> pathname to an existing file
>> 
>> normally the system crashes after evaluation (or when quitting LW)...
>> |#
>> 
>> 
>> -------------------------------------------------------
>> Denis Pousseur
>> 70 rue de Wansijn
>> 1180 Bruxelles, Belgique
>> 
>> Tel : 32 (0)2 219 31 09
>> Mail :  denis.pousseur@compositeurs.be
>> Website : http://compositeurs.be/pousseur
>> -------------------------------------------------------
>> 
>> 
>> 
> 
> 
> 



-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@compositeurs.be
Website : http://compositeurs.be/pousseur
-------------------------------------------------------





Re: A Mac OS X very specific question

>>>>> On Sat, 28 Oct 2006 09:09:36 +0200, Denis Pousseur said:
> 
> Gosh ! I'm to stupid ! It works perfectly now...
> Your "quick glance" is more accurate than a few ours of mine...
> 
> Thanks a lot !
> 
> Denis
> 
> PS : if I can abuse of your knowledge...: must a foreign structure define in
> lisp be deallocated, even if the foreign procedure doesn't require an
> explicit release ? (the FSSpec and the FSREF structures don't need release
> as I can read in the Mac doc. However, I free the foreign structure in my
> code. Is it correct ?).

Every foreign object must be released somehow.  Assuming that the APIs can be
called from C with "automatic" variables e.g. like this:

{
  FSRef fr;
  ...
  FSPathMakeRef(...,&fr,...)
}

then I suggest using (fli:with-dynamic-foreign-objects ((fr FSRef)) ...) to
create objects that are released on exit from the form.

-- 
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/


> 
> 
> Le 27/10/06 21:27, « [NOM] » <[ADRESSE]> a écrit :
> 
> > 
> > Don't quote me, but...
> > 
> > At a quick glance, your translation of the FSSpec type is wrong.
> > You've defined the filename element as a pointer to a 64-byte array
> > but the actual definition in the header file is that the filename
> > element is the 64-byte array.  So, you're FSSpec structure isn't long
> > enough and your causing your C heap to be corrupted.
> > 
> > Change the definition of FSSpec to
> > 
> > (define-c-struct FSSpec
> >    (vRefNum :short)
> >    (parID :long)
> >    (StrFilename (:c-array Uint8 64)))
> > 
> > and see what happens.
> > 
> >    - Gary Palter
> >      Principal Software Engineer
> >      Clozure Associates
> >      Cell:  617-947-0536
> > 
> > 
> > On Oct 27, 2006, at 3:14 PM, Denis Pousseur wrote:
> > 
> >> 
> >> Hi,
> >> 
> >> Some procedures on Mac OS X need always the old structure FSSpec
> >> (QuickTime
> >> for instance). I have to transmit a pathname by this way to some
> >> coreAudio
> >> MusicDevice. I found the way to get a FSSpec from a FSRef from a lisp
> >> string... The pathname seems to be correctly transmitted to the
> >> foreign
> >> routines : no error code and the file I want to load is correctly
> >> loaded.
> >> But after several calls to the function (sometimes 1, sometimes
> >> more...) LW
> >> crashes, often when quitting. It¹s impossible for me to understand
> >> if the
> >> problem is in my codes, in the Mac codes or in the LW codes...
> >> 
> >> I tried to reproduce a very simple example here but, however, it¹s
> >> need some
> >> lines of codes... I'm really sorry.
> >> 
> >> Any suggestion will be very appreciated !
> >> 
> >> Thanks
> >> 
> >> Denis
> >> 
> >> 
> >> 
> >> (defpackage "PACKAGE-FOO"
> >>   (:nicknames foo) (:use cl fli))
> >> 
> >> (in-package :foo)
> >> 
> >> 
> >> (define-c-typedef Uint8 (:unsigned :char))
> >> (define-c-typedef Uint32 (:unsigned :long))
> >> 
> >> 
> >> #|
> >> declaration in Files.h :
> >> struct FSRef {
> >>   UInt8               hidden[80];             /* private to File
> >> Manager;
> >> need symbolic constant */
> >> };
> >> 
> >> typedef struct FSRef                    FSRef;
> >> |#
> >> 
> >> (define-c-struct FSRef  (hidden (:c-array Uint8 80)))
> >> 
> >> 
> >> #|
> >> declaration  in Files.h :
> >> struct FSSpec {
> >>   short               vRefNum;
> >>   long                parID;
> >>   StrFileName         name;                   /* a Str63 on MacOS*/
> >> };
> >> 
> >> typedef struct FSSpec                   FSSpec;
> >> |#
> >> 
> >> (define-c-struct FSSpec
> >>   (vRefNum :short)
> >>   (parID :long)
> >>   (StrFilename (:pointer (:c-array Uint8 64))))
> >> 
> >> #|
> >> declaration  in Files.h :
> >> extern OSStatus  FSPathMakeRef(const UInt8 *path, FSRef *ref, Boolean
> >> *isDirectory)
> >> |#
> >> 
> >> (define-foreign-function (FSPathMakeRef "FSPathMakeRef") ((path
> >> (:reference-pass (:ef-mb-string :limit 255 :null-terminated-p t)))
> >> (ref
> >> (:pointer FSRef)) (isDirectory (:reference-return :boolean))) ;
> >>   :result-type :long)
> >> 
> >> #|
> >> declaration  in Files.h :
> >> extern OSErr  FSGetCatalogInfo(const FSRef *ref, FSCatalogInfoBitmap
> >> whichInfo, FSCatalogInfo *catalogInfo, HFSUniStr255 *outName, FSSpec
> >> *fsSpec, FSRef *parentRef)
> >> |#
> >> 
> >> (define-foreign-function (FSGetCatalogInfo "FSGetCatalogInfo") ((FSref
> >> (:const (:ptr FSRef))) (whichInfo Uint32) (catalogInfo (:ptr :void))
> >> (outName (:ptr :void)) (fsSpec (:ptr fsSpec)) (parentRef
> >> (:ptr :void))) ;
> >>   :result-type :long)
> >> 
> >> ;my function
> >> 
> >> (defmacro with-no-error (code &body body)
> >>   `(let ((error (progn ,.body)))
> >>      (unless (zerop error) (error (format nil "~d ~d" ,code error)))))
> >> 
> >> (defun string->FSSpec (string)
> >>   (let ((FSRef (allocate-foreign-object :type 'FSRef))
> >>         (FSSpec (allocate-foreign-object :type 'FSspec)))
> >>     (with-no-error "FSPathMakeRef" (FSPathMakeRef string FSRef nil))
> >>     (with-no-error "FSGetCatalogInfo" (FSGetCatalogInfo FSRef 0 nil
> >> nil
> >> FSSpec nil))
> >>     (free FSRef) ;I'm not sure about that, but it crashes anyway...
> >>     (free FSSpec)))
> >> 
> >> 
> >> #|
> >> 
> >> (dotimes (i 10) (string->FSSpec pathname-string)) ;<--- put here every
> >> pathname to an existing file
> >> 
> >> normally the system crashes after evaluation (or when quitting LW)...
> >> |#
> >> 
> >> 
> >> -------------------------------------------------------
> >> Denis Pousseur
> >> 70 rue de Wansijn
> >> 1180 Bruxelles, Belgique
> >> 
> >> Tel : 32 (0)2 219 31 09
> >> Mail :  denis.pousseur@compositeurs.be
> >> Website : http://compositeurs.be/pousseur
> >> -------------------------------------------------------
> >> 
> >> 
> >> 
> > 
> > 
> > 
> 
> 
> 
> -------------------------------------------------------
> Denis Pousseur
> 70 rue de Wansijn
> 1180 Bruxelles, Belgique
> 
> Tel : 32 (0)2 219 31 09
> Mail :  denis.pousseur@compositeurs.be
> Website : http://compositeurs.be/pousseur
> -------------------------------------------------------
> 
> 
> 
> 


Updated at: 2020-12-10 08:47 UTC