2013-07-10 11 views
6

Ho creato una libreria di giocattoli C++ per creare rapidamente una finestra Qt da Lisp. So che esiste qt comune, sto solo cercando di imparare come usare cffi.Lisp, cffi, let e memory

In questo momento, ho 4 funzioni binded:

  • creare applicazione: creare un QApplication e restituire un puntatore
  • creare dei finestrini: creare un QMainWindow e restituire un Poiner
  • spettacolo: spettacolo la finestra specificata come argomento
  • exec: la funzione exec Qt

Ecco un codice Lisp che funzionano perfec tly:

(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) 

Ma se io uso LET o LET * ... Ho un difetto di memoria!

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

Qualcuno sa perché?

Sto usando SBCL:

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

Grazie.

risposta

2

vorrei suggerire di effettuare le seguenti operazioni:

  1. Dal momento che si sta scrivendo libreria C++ e con i suoi simboli da Lisp, assicurarsi di utilizzare extern "C" dichiarazioni - quelli sono necessari per garantire che compilatore C++ non lo fa mangle nomi.

  2. Verificare che la libreria funzioni in un'applicazione C (non C++). Ciò garantirà che la libreria stessa funzioni (ad es. Non genera eccezioni C++).

UPD:

ho cercato di eseguire il codice e aveva lo stesso incidente. Il problema sembra essere nella tua funzione create_application. Ho allegato la mia versione fissa di questa funzione allo http://paste.lisp.org/display/138049.

Concretamente, ci sono 2 problemi:

  1. create_application allocato v sulla pila. Il codice successivo (vale a dire il binding let) lo sovrascrive.

  2. argv dovrebbe essere NULL -terminated. Ad esempio, dovrebbe contenere gli elementi argc+1 - l'ultimo elemento è NULL. (Qt sembra non usarlo, ma è buona abitudine scrivere codice in base alle specifiche).

Nel tuo caso, l'allocazione dello stack è il problema - sembra che let vincolante sovrascrive il valore di v sulla pila, crash SBCL.L'utilizzo di malloc o new per allocare argv nell'heap risolve questo problema.

+1

Grazie per la risposta! Uso già extern "C", si può guardare il mio codice qui: http://pastebin.archlinux.fr/464826 Bene, si sta lavorando in Lisp se uso defparameter e non lasciare, quindi credo che sia non è un'eccezione C++ ... ma ci proverò comunque e ti farò sapere. – Filippo

+0

grazie, funziona! Ma solo con Clisp, ho ancora lo stesso errore con SBCL. Qualche indizio? – Filippo