To interface to a C function which takes a pointer to a string form and puts a string in the memory pointed to by result , declared like this:
void evalx(const char *form, char *result);
(fli:define-foreign-function evalx
((form (:reference-pass :ef-mb-string))
(:ignore (:reference-return
(:ef-mb-string :limit 1000)))))
(evalx "(+ 2 3)")
=>
"5"
Now suppose instead that you want your C program to call a similar routine in a LispWorks for Windows DLL named "evaluator", like this:
{
typedef void (_stdcall *evalx_func_type)(const char *form, char *result);
HINSTANCE dll = LoadLibrary("evaluator");
evalx_func_type evalx = (evalx_func_type) GetProcAddress(dll, "evalx");
char result[1000];
evalx("(+ 2 3)", result);
printf("%s\n", result);
}
You would put this foreign callable in your DLL built with LispWorks:
(fli:define-foreign-callable
("evalx" :calling-convention :stdcall)
((form (:reference :ef-mb-string
:lisp-to-foreign-p nil
:foreign-to-lisp-p t))
(result (:reference (:ef-mb-string :limit 1000)
:lisp-to-foreign-p t
:foreign-to-lisp-p nil)))
(multiple-value-bind (res err)
(ignore-errors (read-from-string form))
(setq result
(if (not (fixnump err))
(format nil "Error reading: ~a"
err)
(multiple-value-bind (res err)
(ignore-errors (eval res))
(if (and (not res) err)
(format nil "Error evaluating: ~a"
err)
(princ-to-string res)))))))
Note: you could use
:reference-return
and
:reference-pass
in the foreign callable definition, but we have shown
:reference
with explicit
lisp-to-foreign-p
and
foreign-to-lisp-p
arguments to emphasise the direction of each conversion.
For information on how to create a LispWorks DLL, see "Creating a dynamic library" in the LispWorks User Guide .