Subject: [clisp-list] :malloc-free allocation -- here: instance methods

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Apr 9 04:03:05 2003

Hi,

Berkeley DB's C-level interface uses DB->get(...) instead of a fixed function like DB_get(...)
How could one interface to this? A possible way is explored here.

			On instance methods
One could use
(def-c-struct DB
  (get (c-function (:arguments ...) ...))
  (put (c-function ...))
  ...many others function slots)
to have CLISP create callable foreign-function objects that match C's DB->put().

(def-call-out db-create ; which you already must have
  (:arguments (DB (c-ptr c-pointer) :out)
              ...))
Then
(funcall
  (slot 'get ; create foreign-function object out of DB->get slot
   (foreign-value
    (foreign-address-variable ; which nobody has but me
     ; - much like cast: foreign-address -> foreign-variable
     (nth-value 1 (db-create ...)) ; that DB pointer
     'DB)))
  db-txn key data flags)
One should memoize the foreign-function object, instead of creating a new one for each call.

However, duplicating the DB structure in Lisp, if the BDB C structure changes, Lisp doesn't know -- not nice!  Unreliable :(

A wrapper around the latter remembers me of typical OO frameworks for Scheme, where you pass the function name as argument (to a closure, which does the dispatch):
(DB-invoke 'get DB-handle ...args) or
(DB-invoke DB-handle 'get ...args)

In CL/CLOS, people tend to prefer
(DB-get DB-handle ...args)
(DB-put DB-handle ...args)

It could still be defined as:
(defmethod DB-get ((DB-handle DB-class) &rest args)
  (apply (memoizing-DB-foreign-function-factory DB-handle 'get) args))
Of course, DB-get could be turned into reader slots of the DB-class CLOS miror -- use slots for presumably often used functions like get and put.

[memoizing-]DB-foreign-function-factory could be implemented in C, to avoid the problem about the C DB struct being changed by the BDB people, without Lisp noticing this change. This would prevent getting out of sync with BDB/
db.h

Regards,
	Jorg Hohle.

---

From: Aurelio Bignoli <[email-masked]>
Date: Fri Apr 11 11:45:08 2003

Hoehle, Joerg-Cyril writes:

 > However, duplicating the DB structure in Lisp, if the BDB C
 > structure changes, Lisp doesn't know -- not nice!  Unreliable :(

this problem could be solved by a program that translates C
declarations into FFI declarations. Such a program is available for
some Common Lisp implementations, e.g LispWorks.

 > [memoizing-]DB-foreign-function-factory could be implemented in C,
 > to avoid the problem about the C DB struct being changed by the BDB
 > people, without Lisp noticing this change. This would prevent
 > getting out of sync with BDB/ db.h

returned function prototype could be a problem: every DB fuction has
its own parameter list. Probably the C factory function should return
a c-pointer which has to be casted to the appropriate FFI:C-FUNCTION
type before APPLYing it.

Another solution could be a C program which, using the offsetof macro,
prints the offset of the relevant DB function pointer members. Its
output could be used to create defconstants in a Lisp file. At
runtime, using FFI:OFFSET and the offset constants, it should be
possible to extract a foreign function pointer from a DB
pointer. Details are left to the reader as exercise :)