From: Hoehle, Joerg-C. <Joe...@t-...> - 2003-04-16 12:29:02
|
Aurelio Bignoli wrote: >void *make_foreign_string (const char *s) This is superfluous. Consider: (def-call-out make-foreign-string (:name "ffi_identity") ; ffi_identity has many many uses (:arguments (s c-string :in :malloc-free)) (:return-type c-pointer) (:language :stdc)) (setf *x* (make-foreign-string "abcd")) #<FOREIGN-ADDRESS #x00BF1B30> You may now also consider FFI[8]> (ffi:deep-malloc 'character "abcde" :count 4) #<FOREIGN-VARIABLE FOREIGN-ALLOC* #x00CC0470> [...] 1. Break FFI[10]> (foreign-value *) "abcd" 1. Break FFI[10]> (describe **) #<FOREIGN-VARIABLE FOREIGN-ALLOC* #x00CC0470> is a foreign variable of foreign type (C-ARRAY-MAX CHARACTER 4). (defun make-foreign-string (s) (ffi:deep-malloc 'ffi:character s :count (length s) :read-only t) But that is not null-terminated. You may use (1+ (length s)), then it would be. :read-only is an indication that the Lisp side will not modify it any more (using (setf foreign-value)). Note that this only works on 1:1 string encodings (e.g. ASCII, ISO-8859-1 etc.). C-POINTER and (or rather exclusive or) :malloc-free >(def-call-out make-foreign-string > (:name "make_foreign_string") > (:arguments (s c-string :in)) > (:return-type c-pointer :malloc-free)) :MALLOC-FREE has no effect with C-POINTER. It it had effect, it would have free'd the memory, thus you'd receive a pointer to invalid memory. That's clearly not what you wish for :) One way to understand when CLISP's FFI considers :malloc-free is to wonder when it needs to convert something to or from Lisp to the alien world. With C-POINTER, no conversion occurs (it's just passing the pointer around that it was given), so no malloc() nor free() is ever performed. This may seem odd, but it somehow makes sense. I'll let people investigate what would happen if it were the other way (hint: consider the implications of the :full keyword of the newly added FOREIGN-FREE). Stability of gcc >[5]>(with-c-var (p 'c-pointer *x*) (cast p '(c-ptr (c-array >character 4)))) >Segmentation fault If it only happens with gcc-2.3.2 and not 2.9.5, then I bet it's time to look at gcc's assembly output (want to generate feedback to gcc-bugs@...) or to dump this version os gcc (generate no feedback). My experience with gcc for the Amiga(mc680x0) was that only some of the releases were able to fully compile CLISP... If CAST looks suspicious, investigate the functional level of FFI that you now know, e.g. FFI::%CAST. OTOH, a bug could lie anywhere, also in CLISP, e.g. with-c-var, ... Regards, Jorg Hohle. |