<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=us-ascii"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    On 05/09/2011 01:49 PM, Martin Simmons wrote:
    <blockquote
      cite="mid:201105091149.p49Bnp7n028813@higson.cam.lispworks.com"
      type="cite">
      <blockquote type="cite">
        <blockquote type="cite">
          <blockquote type="cite">
            <blockquote type="cite">
              <blockquote type="cite">
                <pre wrap="">On Sun, 08 May 2011 14:39:41 +0200, Nitralime  said:
</pre>
              </blockquote>
            </blockquote>
          </blockquote>
        </blockquote>
        <pre wrap="">
Using a finalizer seems to be a possible way to go. But I'm not sure how
this can be done by just using the finalizer parameters "object" and 
"function"
where "function" can't reliablely access "object" (cf. documentation of 
finalizer
in "trivial-garbage"  package)!!

Any help and feedback is very much appreciated!
</pre>
      </blockquote>
      <pre wrap="">
IMHO, attempting to transparently wrap a foreign object with a CLOS object is
not a good design.

Using a finalizer is dangerous because it is difficult to guarantee that the
Lisp wrapper object is retained for the correct lifetime.

For example, consider

(defstruct table
  foreign-pointer)

(defun allocate-table ()
  (make-table :foreign-pointer (foreign-allocate-table)))

(defun allocate-and-munge-table ()
  (let ((table (allocate-table)))
    (foreign-munge-table (table-foreign-pointer table))))

The compiler might not keep the variable "table" alive during the call to the
foreign function foreign-munge-table.  As a result, the Lisp table object
might be gc'ed in another thread while the foreign code is accessing it.

</pre>
    </blockquote>
    <font face="Consolas">Consider the following sample (pseudo-)code:<br>
      ----------------------------------------------------------<br>
      (defclass table ()<br>
        ((table-pointer :initarg :handle :accessor handle-of)))<br>
      <br>
      (defmethod initialize-instance :after ((self table) &key)<br>
         (let ((table-pointer (handle-of self)))<br>
              (tg:finalize self (lambda () (foreign-destroy-table
      table-pointer)))))<br>
      <br>
      (defmethod get-row ((t table) index)<br>
         (transform-to-lisp-vector (foreign-get-row (hadle-of t)
      index)))<br>
      <br>
      (defmethod move-to ((t table) index)<br>
         (foreign-move-to (handle-of t) index))<br>
      .....<br>
    </font><font face="Consolas">----------------------------------------------------------<br>
      <br>
    </font><font face="Consolas">Now consider a function which creates a
      table instance<br>
      and puts it into a result plist (and has probabely some side
      effects):<br>
      <br>
      (defun call-a-foreign-function (.....)<br>
         (let (....)<br>
              ....<br>
              <call a foreign function which allocates a table object<br>
               and returns a-foreign-table-pointer><br>
              ....<br>
              (let ((result-table (make-instance 'table :handle
      a-foreign-table-pointer))<br>
                    (...))<br>
                   ...<br>
                   ...<br>
                   '(:id   ...<br>
                     :tab  result-table<br>
                     :msg  ...<br>
                     ...))))<br>
      <br>
      The question is now what will happen if you do just<br>
      <br>
          (call-a-foreign-function ...)<br>
      <br>
      or something like this<br>
      <br>
          (getf (call-a-foreign-function ...) :id)<br>
      <br>
      I assume that the unreachable object 'result-table' will be
      garbage collected,<br>
      and the finalization will free the corresponding C table object!<br>
      <br>
      Do you see any misconception (resp. potential danger) here?<br>
      <br>
      Regards<br>
      Nik<br>
      <br>
    </font>
  </body>
</html>