Subject: [clisp-list] Re: Problem with ffi:foreign-pointer

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Fri Sep 12 12:28:32 2003

>Von: Roland Averkamp

>I have a foreign-adress and want to read the double-float at the memory
>location the address points to.
>
>So I tried to change the foreign-address behind a 
>foreign-variable object.

You want to work on memory contents, so you indeed need FOREIGN-VARIABLE objects, or foreign-places (which are symbol macros which encapsulate these objects).

>How can I do this otherwise?
(with-c-var (place 'c-pointer your-foreign-address)
  (cast place '(c-ptr double-float)))
should dereference that.
It's not particularly performant, but it does the job.

If you already have a FOREIGN-VARIABLE object instead of a FOREIGN-ADDRESS, use CAST or DEREF on a place associated with it (see WITH-C-PLACE).
Where did you get the FOREIGN-VARIABLE from?

BTW, maybe you could short-circuit with Aurelio Bignoli who worked on porting BDB (Berkeley DB). He probably faced a similar situation.

Regards,
	Jörg Höhle.

---

From: Aurelio Bignoli <[email-masked]>
Date: Sun Sep 14 07:38:04 2003

Hoehle, Joerg-Cyril writes:

 > BTW, maybe you could short-circuit with Aurelio Bignoli who worked
 > on porting BDB (Berkeley DB). He probably faced a similar
 > situation.

yes, I had to convert a C pointer to one of the following C objects:

1) array of characters
2) string
3) integer

to the corresponding CLISP object and I used the with-c-var...cast
pattern you described. However, after some testing, I discovered that
the use of an ad-hoc C function for the conversion of C ints into
CLISP fixnums gives better performances. Probably the same is true for
the conversion from any non-aggregate C type to the corresponding
CLISP type, such as floats and doubles. 

Here is my solution for ints:

The C ad-hoc conversion function:

int
get_int_data (void *p)
{
  return *(int *)p;
}

Its FFI definition:

(def-call-out ffi-get-int-data
  (:name "get_int_data")
  (:arguments (data c-pointer :in))
  (:return-type int))

Finally, the method used to convert pointer to ints returned by
BerkeleyDB functions:

(defmethod get-foreign-data (data len (type (eql 'integer)))
  (declare (ignore len))
  (ffi-get-int-data data))