Lisp, cffi, let and memory
Asked Answered
C

1

6

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.

Comical answered 10/7, 2013 at 22:43 Comment(0)
H
2

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.

Haddix answered 13/7, 2013 at 7:8 Comment(2)
Thanks for your answer ! I already use extern "C", you can look at my code here : pastebin.archlinux.fr/464826 Well, it is working in Lisp if I use defparameter and not let, so I guess it's not a C++ exception...but I'll try it anyway and I'll let you know.Comical
thanks, it works ! But only with Clisp, I still have the same error with SBCL. Any clue ?Comical

© 2022 - 2024 — McMap. All rights reserved.