Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp, cffi, let and memory

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.

like image 704
Filippo Avatar asked Jul 10 '13 22:07

Filippo


1 Answers

I would suggest you do the following:

  1. 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.

  2. 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:

  1. create_application allocated v on stack. Subsequent code (i.e., the let binding) overwrites it.

  2. 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.

like image 114
dmitry_vk Avatar answered Nov 15 '22 09:11

dmitry_vk