Lisp Knowledgebase
Title: How do you pass a pointer to a Lisp function to a calling program?
ID: 17002
Product: LispWorks Version: 4.1 OS: All | |
Description: Define the function using FLI:DEFINE-FOREIGN-CALLABLE and call FLI:MAKE-POINTER with the :SYMBOL-NAME keyword to create a foreign pointer. Use a foreign variable to hold the address of the foreign callable. On Win32 platforms, take care to get the calling convention correct (:cdecl or :stdcall ). There's an example for Linux below. This example was built as a DLL on MS Visual C++ ---------------- win32-fcexample.c -------------------------------- int(*FuncPtr1)(int, int) ; int (*FuncPtr)() ; void __declspec(dllexport) test (void) { (*FuncPtr)() ; (*FuncPtr1) ( (*FuncPtr1)(3,4), 87) ; } void __declspec(dllexport) initmyapplication (int (*funca)(int,int), int(*funcb) ()) { FuncPtr = funcb ; FuncPtr1 = funca ; } ---------------- win32-fcexample.c -------------------------------- ---------------- win32-fcexample.lisp ----------------------------- ;; Load time (fli:define-foreign-function (test "test") () :result-type :int :module :my-dll :calling-convention :cdecl) (fli:define-foreign-callable ("lispval" :result-type :int :calling-convention :cdecl) () (format t "One call~%") 97) (fli:define-foreign-callable ("another" :result-type :int :calling-convention :cdecl) ((x :int) (y :int)) (format t "Another call ~a , ~a~%" x y) (* x x y)) (fli:define-foreign-function (init-my-application "initmyapplication") ((x :ptr) (y :ptr)) :module :my-dll) ;; Initialization (defun init() (fli:register-module :my-dll :real-name C:\\fcexample\\Debug\\fcexample.dll") (init-my-application (fli:make-pointer :symbol-name "another") (fli:make-pointer :symbol-name "lispval"))) ;; Runtime (defun do-test () (init) (test)) ---------------- win32-fcexample.lisp ----------------------------- This example is for Linux, built by gcc -shared -o fcexample.so linux-fcexample.c -------------linux-fcexample.c ------------------------------------ int(*FuncPtr1)(int, int) ; int (*FuncPtr)() ; void test (void) { (*FuncPtr)() ; (*FuncPtr1) ( (*FuncPtr1)(3,4), 87) ; } void initmyapplication (int (*funca)(int,int), int(*funcb) ()) { FuncPtr = funcb ; FuncPtr1 = funca ; } -------------linux-fcexample.c ------------------------------------ -------------linux-fcexample.lisp---------------------------------- ;; Load time (fli:define-foreign-function (test "test") () :result-type :int :module :my-dll :calling-convention :cdecl) (fli:define-foreign-callable ("lispval" :result-type :int) () (format t "One call~%") 97) (fli:define-foreign-callable ("another" :result-type :int) ((x :int) (y :int)) (format t "Another call ~a , ~a~%" x y) (* x x y)) (fli:define-foreign-function (init-my-application "initmyapplication") ((x :ptr) (y :ptr)) :module :my-dll) ;; Initialization (defun init() (fli:register-module :my-dll :real-name "/tmp/fcexample.so") (init-my-application (fli:make-pointer :symbol-name "another") (fli:make-pointer :symbol-name "lispval"))) ;; Runtime (defun do-test () (init) (test)) -------------linux-fcexample.lisp---------------------------------- | |
See Also: Workaround: Patch: | |
Hardware:N/A | |
Summary: | |
Bug#: | |
Patch Enhancement#: | |
Reported: |