Lisp, cffi, let and memory - pointers

I've build some toy C++ library to quickly create a Qt window from Lisp. I know that common-qt exists, I'm just trying to learn how to use cffi.
Right now, I have 4 binded functions :
create-application : create a QApplication and return a pointer
create-window : create a QMainWindow and return a poiner
show : show the window specified as argument
exec : Qt exec function
Here is a lisp code that work perfectly :
(defctype t-app :pointer)
(defctype t-window :pointer)
(defcfun (create-application "create_application" ) t-app)
(defcfun (exec "exec") :void (app t-app))
(defcfun (create-window-aalt "create_window_aalt") t-window)
(defcfun (show "show") :void (o t-window))
(defparameter a (create-application))
(defparameter w (create-window-aalt))
(show w)
(exec a)
But if I use LET or LET*...I have a memory fault !
(let* ((a (create-application)) (w (create-window-aalt)))
(show w)
(exec a))
CORRUPTION WARNING in SBCL pid 1312(tid 140737353860992):
Memory fault at a556508 (pc=0x7ffff659b7f1, sp=0x7ffff2bbe688)
The integrity of this image is possibly compromised.
Exiting.
Does someone know why ?
I am using SBCL :
env LD_LIBRARY_PATH=`pwd` \
env LD_PRELOAD=/usr/lib/libQtGui.so.4 \
sbcl --script aalt.lisp
Thanks.

I would suggest you do the following:
Since you are writing library C++ and using its symbols from Lisp, make sure that you use extern "C" declarations - those are needed to ensure that C++ compiler does not mangle names.
Check that your library works in a C (not C++) application. This will ensure that the library itself is working (e.g., it does not throw C++ exceptions).
UPD:
I've tried to run your code and had the same crash. The problem seems to be in your create_application function. I've attached my fixed version of this function at http://paste.lisp.org/display/138049.
Concretely, there are 2 problems:
create_application allocated v on stack. Subsequent code (i.e., the let binding) overwrites it.
argv should be NULL-terminated. I.e., it should contain argc+1 elements - the last element is NULL. (Qt seems to not use this, but it is good habit to write code according to specs).
In your case, the stack allocation is the problem - it seems that let binding overwrites the value of v on stack, crashing SBCL. Using malloc or new to allocate argv on heap fixes this issue.

Related

How do I use the live-code feature in sbcl?

I am trying to get live-coding to work in lisp. i have the file t.cl which contains only this line: (loop(write(- 2 1))). Now, when i run the file in bash with sbcl --load t.cl --eval '(quit)', it runs the line, but when I try to edit the file in another terminal and save it while it runs, nothing changes ..
Why your example fails
When running sbcl --load t.cl --eval '(quit)' in a shell, what this does is spin-up a SBCL Lisp image in a process, compile the file and run it. You then modify the file and save it to your disk. This last action is of no concern to the already running SBCL process, which has already compiled the previous file. SBCL read the file once when you asked it to, once it has the compiled instructions to run, it has no reason to look at the file again unless you explicitly ask it to.
A 'live' example with Emacs+SLIME
In order to perform 'live' changes to your running program, you must interact with the already running Lisp image. This is easily doable with Emacs+Slime. You can, for example, have a loop like so:
(defun foo (x) (+ x 3))
(dotimes (it 20)
(format t "~A~%" (foo it))
(sleep 1))
and then recompile foo during execution within the REPL with a new definition:
(defun foo (x) (+ x 100))
Another thread will be used to recompile the function. The new function will be used for future calls as soon as its compilation is finished.
The output in the REPL will look like:
3
4
5
CL-USER> (defun foo (x) (+ x 100))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
103
104
105
...
This would also work with the new definition of foo being compiled from another file as opposed to being entered directly in the REPL.
Working from the system shell
While you can already use the example above for development purposes, you might want to interact with a running SBCL Lisp image from the shell. I am not aware of how to do that. For your exact example, you want to get SBCL to reload eventual files that you have modified. A brief look at the SBCL manual doesn't seem to provide ways to pipe lisp code to an already running SBCL process.

How can the mouse be moved programatically in Common Lisp?

The code should run on Windows 10. I tried asking on Reddit, but the ideas are Unix/Linux only. There's also CFFI, but I didn't understand how to use it for this problem (the main usability part of the documentation I found is just an elaborate example not related to this problem).
I also looked through the SetCursorPos of Python, and found that it calls ctypes.windll.user32.SetCursorPos(x, y), but I have no clue what that would look like in CL.
And finally, there's CommonQt, but while there seems to be QtCursor::setPos in Qt, I couldn't find the CL version.
The function called by the Python example seems to be documented here. It is part of a shared library user32.dll, which you can load with CFFI,
(ql:quickload :cffi)
#+win32
(progn
(cffi:define-foreign-library user32
(:windows "user32.dll"))
(cffi:use-foreign-library user32))
The #+win32 means that this is only evaluated on Windows.
Then you can declare the foreign SetCursorPos-function with CFFI:DEFCFUN. According to the documentation, it takes in two ints and returns a BOOL. CFFI has a :BOOL-type, however the Windows BOOL seems to actually be an int. You could probably use cffi-grovel to automatically find the typedef from some Windows header, but I'll just use :INT directly here.
#+win32
(cffi:defcfun ("SetCursorPos" %set-cursor-pos) (:boolean :int)
(x :int)
(y :int))
I put a % in the name to indicate this is an internal function that should not be called directly (because it is only available on Windows). You should then write a wrapper that works on different platforms (actually implementing it on other platforms is left out here).
(defun set-cursor-pos (x y)
(check-type x integer)
(check-type y integer)
#+win32 (%set-cursor-pos x y)
#-win32 (error "Not supported on this platform"))
Now calling (set-cursor-pos 100 100) should move the mouse near the top left corner.
There are two problems here:
How to move the mouse in windows
How to call that function from CL.
It seems you have figured out a suitable win32 function exists so the challenge is to load the relevant library, declare the functions name and type, and then call it. I can’t really help you with that unfortunately.
Some other solutions you might try:
Write and compile a trivial C library to call the function you want and see if you can call that from CL (maybe this is easier?)
Write and compile a trivial C library and see if you can work out how to call it from CL
Write/find some trivial program in another language to move the mouse based on arguments/stdin and run that from CL

Let, flet, macrolet : is there a way to do a "class-let"?

I have a macro which defines a class under certain rules, pseudo-code :
(defvar *all-my-classes* nil)
(defmacro my-macro (param)
`(if ,param
(progn
(defclass class-A () ...)
(push class-A *all-my-classes*))
(progn
(defclass class-B () ...)
(push class-B *all-my-classes*))))
I want to test the behaviour of the macro. Let is a convenient tool to mock variables. If I have an instance of *all-my-classes* running, I just have to do :
(let ((*all-my-classes* my-new-value)) ; generally `nil` for the test
(my-macro false))
But I would like to conserve the correspondance between *all-my-classes* and the classes defined. Since I want to test all the cases, let us suppose class-A is defined in the current environment, and i want to test if running (my-macro false) correctly defines class-B.
Since it is just a test, I would like the test to assert that class-B is currently defined, and that class-A is undefined in the current local environment; then when the test is over, class-B is undefined in the global environment, and class-A is still defined (without any alteration).
This way would be the best for my use :
(let ((*all-my-classes* nil))
(class-let ((class-A nil) ; or a way to map to a pre-defined
(class-B nil)) ; empty class temporarily.
(my-macro false)
(and
;; assert that the class is added to the list
(eql (length *all-my-classes*) 1)
;; assert that class-A is not defined
(null (find-class 'class-A))
;; assert that class-B is defined
(find-class 'class-B))))
I've searched to see if I can undefine a class, but it seems to be complex and implementation-dependent. And I want to preserve the current environment.
Restarting LISP each time for each tests is too long, and I would prefer a solution without having to load-unload packages for each tests (I don't know if it could work and if the classes will be garbage-collected when unloading the package...).
Thank you for your answers.
I do not think so.
The mechanism of how classes are stored is completely implementation defined, they just need to conform to the MOP (at least as far as it is mandated by the standard). However, the MOP does not prescribe anything that would make the classes registry dynamic. In fact, types and class names are specified to be part of the global environment (CLHS ch. 3.1.1.1), so it would be difficult for a conforming implementation to get dynamic here.
As you wrote, there is also no specified way to get rid of a class once defined.
As a rationale, I think that without this it would be very difficult to provide the kind of optimized runtime that the existing implementations have. Class lookup needs to be fast.
Now, to get to the meta question: what are you trying to do? Usually, while code is data, you should not confuse program logic with the programmed logic. What you propose looks like it might be intended to have code represent data. I'd advise to think about a clean separation and orthogonal representation.

Common Lisp CFFI: pointer to the pointer

I am trying to write the CFFI wrapper for Sundials CVODE library. SWIG was choking on Sundials headers since they are quite interconnected and SWIG couldn't find the right headers, so I did it by hand: a bit laborious but I've managed.
Now I'm trying to test if it works correctly. For now, just simply creating the "problem object" and deleting it. That is where the problem starts. So, the "problem object" is allocated via function
SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter);
For which I created the wrapper:
(cffi:defcfun "CVodeCreate" :pointer
(lmm :int)
(iter :int))
PS. SUNDIALS_EXPORT (at least on Unix's) is basically nothing.
Now, to destroy the object, Sundials uses its own function:
SUNDIALS_EXPORT void CVodeFree(void **cvode_mem);
So, I need to pass it the reference to the object created by CVodeCreate. In C, if my memory is not at fault, I would have done something like CVodeFree(&problem_object). In CL I've written this wrapper for the function:
(cffi:defcfun "CVodeFree" :void
(cvode-mem :pointer))
So, here COVDE-MEM is a pointer to a pointer. Question is how to get the pointer of the pointer in CL/CFFI? Here is the beginning of the code:
(defvar *p* (cvodecreate 1 2))
(PS. Don't worry about the numbers passed to CVODECREATE, they just tell which methods to use, still need to defined constants to make it more readable)
So *P* is something like
#.(SB-SYS:INT-SAP #X7FFFE0007060)
If I pass it directly to CVODEFREE, it ends up in error:
CL-USER> (cvodefree *p*)
; Evaluation aborted on #<SIMPLE-ERROR "bus error at #X~X" {1005EC9BD3}>.
I've tried passing (CFFI:POINTER-ADDRESS *P*) but it results in similar "bus error..." (not even sure if this function returns what I need). I've also tried to do (CFFI:MAKE-POINTER (CFFI:POINTER-ADDRESS *P*)), once again without any success.
This question suggests this approach:
(cffi:with-foreign-object (p :pointer)
(setf (cffi:mem-ref p :pointer) (cvodecreate 1 2))
(cvodefree p))
This works (at least it doesn't throw an error). I think I understand how it works: it creates (allocates the memory for) a pointer-to-a-pointer P, whose MEM-REF (or in C terms would be dereferencing *p) is filled by the result on CVODECREATE. Finally, I'm passing this pointer-to-a-pointer to CVODEFREE, which expects exactly this. Finally, the memory allocated for P is freed once the form finished. Is this the correct approach? And is it the only one I can take?
Yup, your approach looks right, here is a small test to show the concept that can be run straight from the repl.
(let* (;; a float
(v0 32s0)
;; a pointer to a float foreign memory
(p0 (cffi:foreign-alloc :float :initial-element v0)))
;; a new pointer
(cffi:with-foreign-object (p1 :pointer)
;; make the new pointer point to the first pointer
(setf (cffi:mem-aref p1 :pointer) p0)
;; dereferencing twice should give you the original number
(cffi:mem-aref (cffi:mem-aref p1 :pointer) :float)))
p.s. I'm sure you knew this by now, sorry it took so long to get you an answer. Hopefully this can help others

CL and SWIG: working example?

Doing a SWIG tutorial, and using the example.c, example.i as they provided there. I generated lisp file with swig -cffi example.i.
But when I run test.lisp with SBCL, i get a complaint about undefined alien function, as well as complaints when compiling the example.lisp itself. I'm pretty sure I still have to compile my example.c into a library and then somehow tell SBCL to load it! But the docs are very scant on this, except for this.
Can somebody tell me how to do this or is there a better way than SWIG to automatically generate CFFI bindings from C/C++ sources??
sbcl output:
...
;
; caught STYLE-WARNING:
; Undefined alien: "fact"
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
;
; caught STYLE-WARNING:
; Undefined alien: "my_mod"
...
test.lisp
;call C functions defined in example.c
(require :cffi)
;;;(require :example "example.lisp")
(load "example.lisp")
(fact 2)
(quit)
First, you need to compile the C library. Do something like:
gcc -shared example.c -o libexample.so
Of course, for a complex existing library compilation could be considerably more complex -- if you're wrapping an existing library, it probably comes with some sort of Makefile to help you build it.
Then, in Lisp, use CFFI to define and load the library. This seems to be the main part that you're missing.
(cffi:define-foreign-library libexample
(t (:default "libexample"))) ;; note no .so suffix here
(cffi:use-foreign-library libexample)
This part:
(t (:default "libexample"))
is a conditional which you can use to give different loading instructions for different platforms. (t ...) is the catchall option, much like with COND. You can find the exact syntax in the documentation for define-foreign-library.
You would now normally use cffi:defcfun and so on to define the functions in the library. This is what the SWIG-generated file does for you, so load it:
(load "example.lisp")
You can now call the functions as normal Lisp functions:
(fact 5)
=> 120

Resources