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