Lisp, cffi, let and memory

I created some toy in the 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.

I now have 4 attached functions:

  • create-application: create QApplication and return a pointer
  • create-window: create a QMainWindow and return a poiner
  • show: show the window specified as an argument
  • exec: Qt exec function

Here is the lisp code that works fine:

(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 error!

 (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 anyone know why?

I am using SBCL:

 env LD_LIBRARY_PATH=`pwd` \ env LD_PRELOAD=/usr/lib/libQtGui.so.4 \ sbcl --script aalt.lisp 

Thanks.

+6
source share
1 answer

I suggest you do the following:

  • Since you are writing a C ++ library and using its symbols from Lisp, make sure you use extern "C" declarations - they are necessary to ensure that the C ++ compiler does not manage names.

  • Make sure your library works in C application (not C ++). This ensures that the library itself works (for example, it does not throw C ++ exceptions).

UPD:

I tried to run your code and had the same crash. The problem seems to be in your create_application function. I am attached to my fixed version of this function at http://paste.lisp.org/display/138049 .

Specifically, there are 2 problems:

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

  • argv must be NULL terminated. Ie, it must contain argc+1 elements - the last element is NULL. (Qt doesn't seem to use this, but it's a good habit to write code according to the specifications).

In your case, the problem is with the distribution of the stack - it seems that the let binding overwrites the value of v on the stack, SBCL failed. Using malloc or new to allocate argv on the heap fixes this problem.

+2
source

Source: https://habr.com/ru/post/949166/


All Articles