On Mon, 2005-10-24 at 23:43 +0100, Luis Oliveira wrote:
Right now the user should free the first string (or whatever) by himself. I plan to add some options to DEFCVAR to make this automatic (something like what CLISP has). For example the setter that DEFCVAR defines would automatically free the previous contents of the foreign var. [...] Any suggestions on how to handle this better? Or is the automatic solution I mention before (regarding the setter) enough?
The point is that if the foreign var does not belong to you, some other component of the library might overwrite the variable you are setting. What can one then do if the pointer to the data that is to be freed is lost?
To make my case clear, suppose that you have a C variable
const char *error_message;
This is quite common in C, as the error_message is expected to be statically allocated. However, somewhere in your code you define *error-message* to be the foreign variable pointing to it and you do
(setf *error-message* "Unable to access temporary directory")
Now some other component of the library overwrites this variable because a different error condition happened
error_message = "File not found";
and then your lisp code tries to
(foreign-free (mem-ref (get-var-ptr '*error-message*) :pointer))
Kaboom! :-)
In ECL's implementation of UFFI, foreign variables are defined once and a property list is associated to the symbol. Whenever you set a foreign variable with some data, the foreign data generated by the lisp is stored in that property list, hence preventing garbage collection.
When you set the same variable a second time, the original lisp value is lost and then it is garbage collected. An alternative would be to free the value as soon as it is removed from the property list.
Regards