4.4.1 Strings and foreign callables

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);

you would define in Lisp:

(fli:define-foreign-function evalx 
    ((form (:reference-pass :ef-mb-string))
     (:ignore (:reference-return
               (:ef-mb-string :limit 1000)))))

and call

(evalx "(+ 2 3)")

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:

    ("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"
            (multiple-value-bind (res err)
                (ignore-errors (eval res))
              (if (and (not res) err)
                  (format nil "Error evaluating: ~a"
                (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 .

LispWorks Foreign Language Interface User Guide and Reference Manual - 14 Mar 2008