2013-07-10 22 views
6

Zbudowałem bibliotekę zabawek C++, aby szybko utworzyć okno Qt z Lisp. Wiem, że common-qt istnieje, próbuję tylko nauczyć się korzystać z cffi.Lisp, cffi, let and memory

Teraz mam 4 binded funkcje:

  • tworzenie-aplikacji: tworzenie QApplication i zwraca wskaźnik
  • create-okno: stworzyć QMainWindow i zwracają poiner
  • Pokaż: Pokaż okno określony jako argument
  • exec: Qt funkcja exec

Oto LISP kod, który działa 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) 

Ale jeśli użyję LET lub LET * ... Mam błąd pamięci!

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

Czy ktoś wie, dlaczego?

Używam SBCL:

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

Dzięki.

Odpowiedz

2

Proponuję wykonać następujące czynności:

  1. Skoro piszesz biblioteki C++ i wykorzystuje swoje symbole z Lisp, upewnij się, że używasz extern "C" deklaracji - te są potrzebne, aby zapewnić, że kompilator C++ nie robi nazwy mangle.

  2. Sprawdź, czy twoja biblioteka działa w aplikacji C (nie C++). Zapewni to, że sama biblioteka działa (np. Nie generuje wyjątków C++).

UPD:

Próbowałem uruchomić swój kod i miał taką samą katastrofę. Problem wydaje się być w twojej funkcji create_application. Dołączyłem moją stałą wersję tej funkcji pod adresem http://paste.lisp.org/display/138049.

Konkretnie, są 2 problemy:

  1. create_application przydzielone v na stosie. Kolejny kod (tj. Powiązanie let) zastępuje go.

  2. argv powinien być NULL -terminowany. Np. Powinien zawierać elementy argc+1 - ostatni element ma wartość NULL. (Wydaje się, że Qt tego nie używa, ale dobrze jest pisać kod zgodnie ze specyfikacjami).

W twoim przypadku, przydział stos jest problem - wydaje się, że let wiązania nadpisuje wartość v na stosie, upaść SBCL.Użycie malloc lub new do przydzielenia argv na stertach rozwiązuje ten problem.

+1

Dzięki za odpowiedź! Już używam extern "C", możesz spojrzeć na mój kod tutaj: http://pastebin.archlinux.fr/464826 Cóż, działa on w Lispie, jeśli używam defragametru i nie pozwalam, więc myślę, że to nie jest to wyjątek C++ ... ale i tak spróbuję, a dam ci znać. – Filippo

+0

dzięki, to działa! Ale tylko z Clisp, nadal mam ten sam błąd z SBCL. Jakaś wskazówka? – Filippo