FLI again
davef@xanalys.com writes:
> Strange, it seem my mails don't find their way to this list.
>
> Hello Friedrich
>
> I've not seen (as the list owner) any bounced message from you. It's
> quite common that people attempt to post from addresses which are not
> on the list, when this happens I do inform them.
>
> So here we go again:
> I have read the Common Lisp cookbbook and looked at how to call an
> external C function. (example (calling gethostname)
>
> Well I extracted that function from the header and let the
> foreign-parser do the job
>
> I than have come up with this (IMHO wrong solution, which should
> crash)
> (defun get-hostname ()
> (let* ((limit 256))
> (fli:with-dynamic-foreign-objects ((buffer (:char)))
> (let ((ret-val (gethostname buffer limit)))
> (if (> ret-val 0)
> (break)
> (fli:convert-from-foreign-string buffer))))))
>
>
> Well why do I think it should crash? I'm not allocating any space for
> the external buffer.
The questions still persists, why doesn't it crash?
>
>
> I than checked the knowledgebase and bound 17004, but that confuses me
> even more.
>
> Was exactly was it that confused you? The title of Example 2 does seem
> to suggest that a supplied Lisp string can be modified by a foreign
> function call (which is not true) though the text clearly states that
> a new string is returned.
>
> So maybe someone can bring into some light.
> What I want to do
> I want to allocate a Lisp String (such that it can be handled by the
> Lisp GC) than I wont to hand this string over to C which fills it well
> on return it should be still a valid Lisp string.
>
> Why do you want to first allocate the string in Lisp?
I want Lisps GC to take care of the things. And it's was or is
obviously (wrong?) that it should be the "cheapest" way. Allocate
space for a string one time not more often.
>
> What is the right way doing it?
>
>
> Here's three definitions which work for me:
>
>
> (fli:define-foreign-function (getdomainname-1 "getdomainname" :source)
> ((:ignore (:reference-return (:ef-mb-string :limit 256)))
why an :ignore?
> (:constant 256 :integer))
> )
>
>
>
> (fli:define-foreign-function (%getdomainname "getdomainname" :source)
> ((buffer :pointer)
> (len :integer))
> :result-type :integer)
>
> (defun getdomainname-2 (len)
> (fli:with-dynamic-foreign-objects ()
> (let ((buffer (fli:allocate-dynamic-foreign-object
> :type :char :nelems len)))
> (when (eq (%getdomainname buffer len) 0)
> (fli:convert-from-foreign-string buffer :length len)))))
Well in my understanding I have to free the allocated object. If I do
not than it should be a memory leak. What am I missing?
Well now I have some more ways but I still do not understand much
more. So I probably have to rephrase the questions
a) if I use fli:alllcate-dyn... than in my understanding and according
to the docs I have to free that memory by hand.
b) can I do this?
(let ((str (make-string limit)))
(fill-str-in-c-function str ...)
and got it simply back without a new string getting allocated?
c) I do not understand what the "right" solutions should be. Some of
my solutions work although I think they should not! See the first
question.
So I would appriciate if someone could clarfiy that a bit.
Thanks
Friedrich