From: Neil Cohen
Subject: Strings in Lispworks Foreign Language Interface
Date: 
Message-ID: <kqIr8.13959$ud6.486999@typhoon.austin.rr.com>
I'm having trouble packing a string into a struct into Lispworks FLI.   When
I define a structure and try packing a string into one of its slots, I get
garbage when I try referencing that slot:

;; Defines the struct
(fli:define-c-struct shuttle

...   lots of other slots
(exception_type :pointer))


;;Packs the string into the slot.
(defun pack-shuttle (l-card)
  "Packs the init-info struct."
  (fli:with-foreign-string (hint-ptr hint-elt-cnt hint-byte-cnt)
      "This is a string"
     (declare (ignore hint-elt-cnt hint-byte-cnt))
(setf
     (fli:foreign-slot-value shuttle-alloc 'EXCEPTION_TYPE) hint-ptr)))

;;Tries referencing  some shuttle:

(print (fli:convert-from-foreign-string
          (fli:foreign-slot-value shuttle 'exception_type)))

  I get garbage.   "N^W"
  This same mechanism, though --- declaring the type a pointer, using
with-foreign-string to set the value, and convert-from-foreign-string ---
does work to make a function return a string:

Calling the following function and decoding with convert-from-foreign-string
does produce "This is a string"
(fli:define-foreign-callable ("return_string" :result-type :pointer
                                            :calling-convention :cdecl)
  ( )
 (fli:with-foreign-string
      (hint-ptr hint-elt-cnt hint-byte-cnt)
      "This is a string."
      (declare (ignore hint-elt-cnt hint-byte-cnt))
      hint-ptr))

I've tried making the type declaration in the shuttle more specific, trying
to use :ef-mb-string, but can't get it to parse right   (:pointer
(:ef-mb-string 30)).

Any ideas?

Neil Cohen
Bridge Trix

From: Nils Goesche
Subject: Re: Strings in Lispworks Foreign Language Interface
Date: 
Message-ID: <87u1qobn1i.fsf@darkstar.cartan>
"Neil Cohen" <······@bridgetrix.com> writes:

> I'm having trouble packing a string into a struct into Lispworks FLI.   When
> I define a structure and try packing a string into one of its slots, I get
> garbage when I try referencing that slot:
> 
> ;; Defines the struct
> (fli:define-c-struct shuttle
> 
> ...   lots of other slots
> (exception_type :pointer))

Hmm, this works, for example:

(defpackage "BLARK"
  (:use "COMMON-LISP" "FLI")
  (:export "BLARK"))

(in-package "BLARK")

(fli:define-c-struct (shuttle (:foreign-name "shuttle"))
  (exception-type (:pointer :char)))

(defun blark (text)
  (with-dynamic-foreign-objects ((shuttle shuttle))
    (with-foreign-string (pointer ec bc) text
      (declare (ignore ec bc))
      (setf (foreign-slot-value shuttle 'exception-type) pointer)
      (print (convert-from-foreign-string
              (foreign-slot-value shuttle 'exception-type))))))

CL-USER 6 > (blark:blark "foobar")

"foobar" 
"foobar"

CL-USER 7 > 

Hope it helps, somehow...

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Clive Tong
Subject: Re: Strings in Lispworks Foreign Language Interface
Date: 
Message-ID: <u8z7y7gdx.fsf@scientia.com>
"Neil Cohen" <······@bridgetrix.com> writes:

> I'm having trouble packing a string into a struct into Lispworks FLI.   When
> I define a structure and try packing a string into one of its slots, I get
> garbage when I try referencing that slot:
> 
> ;; Defines the struct
> (fli:define-c-struct shuttle
> 
> ...   lots of other slots
> (exception_type :pointer))
> 
> 
> ;;Packs the string into the slot.
> (defun pack-shuttle (l-card)
>   "Packs the init-info struct."
>   (fli:with-foreign-string (hint-ptr hint-elt-cnt hint-byte-cnt)
>       "This is a string"
>      (declare (ignore hint-elt-cnt hint-byte-cnt))
> (setf
>      (fli:foreign-slot-value shuttle-alloc 'EXCEPTION_TYPE) hint-ptr)))
> 
> ;;Tries referencing  some shuttle:
> 
> (print (fli:convert-from-foreign-string
>           (fli:foreign-slot-value shuttle 'exception_type)))
> 
>   I get garbage.   "N^W"

Isn't the problem that fli:with-foreign-string allocates a string that
is freed at the end of the body ? Hence the structure contains a
pointer that ends up pointing to memory that gets overwritten later.

If you want the string in the structure to remain valid, then you need
to allocate the string on the heap yourself (and free it yourself at a
later time).

(defun pack-shuttle ()
  (setf (fli:foreign-slot-value *shuttle-alloc* 'EXCEPTION_TYPE) 
   (fli:with-foreign-string (hint-ptr hint-elt-cnt hint-byte-cnt)
       "This is a string"
     (let ((the-string 
          (fli:allocate-foreign-object :type :char :nelems hint-byte-cnt)))
       (fli:replace-foreign-object the-string hint-ptr :nelems hint-byte-cnt)
       the-string))))
From: Neil Cohen
Subject: Re: Strings in Lispworks Foreign Language Interface
Date: 
Message-ID: <8nIs8.26322$ud6.1008173@typhoon.austin.rr.com>
Thanks.  I think that solves it.  I suspected that was the problem, but
didn't know a good way to allocate a string.  I was going to try to allocate
space for an array of chars, which struck me as ugly.

    Neil
"Clive Tong" <··········@scientia.com> wrote in message
··················@scientia.com...
> "Neil Cohen" <······@bridgetrix.com> writes:
>
> > I'm having trouble packing a string into a struct into Lispworks FLI

> Isn't the problem that fli:with-foreign-string allocates a string that
> is freed at the end of the body ? Hence the structure contains a
> pointer that ends up pointing to memory that gets overwritten later.