2013-07-10 69 views
6

我已經構建了一些玩具C++庫,以便從Lisp快速創建Qt窗口。我知道common-qt存在,我只是想學習如何使用cffi。Lisp,cffi,let和memory

現在,我有4個綁定功能:

  • 創建的應用程序:創建一個QApplication的,並返回一個指針
  • 創建窗口:創建一個的QMainWindow和返回poiner
  • 顯示:秀指定爲參數
  • EXEC窗口:Qt的執行函數

下面是工作口齒不清代碼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) 

但是,如果使用LET還是讓* ...我有一個內存錯誤!

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

有人知道爲什麼嗎?

我使用SBCL:

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

感謝。

回答

2

我建議你做到以下幾點:

  1. 既然你正在編寫庫C++和使用它的符號從Lisp中,請確保您使用extern "C"聲明 - 這些都需要確保C++編譯器不mangle名字。

  2. 檢查您的庫是否在C(而非C++)應用程序中工作。這將確保庫本身正在工作(例如,它不會拋出C++異常)。

UPD:

我試着運行代碼,並有同樣的崩潰。這個問題似乎在你的create_application函數中。我在http://paste.lisp.org/display/138049附上我的固定版本的這個功能。

具體地說,有2個問題:

  1. 上堆

    create_application分配v。隨後的代碼(即let綁定)會覆蓋它。

  2. argv應該是NULL-終止。即,它應該包含argc+1個元素 - 最後一個元素爲NULL。 (Qt似乎不使用這個,但根據規範編寫代碼是個好習慣)。

在你的情況下,堆棧分配的問題 - 似乎let結合覆蓋的v堆棧的價值,轟然SBCL。使用mallocnew在堆上分配argv可修復此問題。

+1

感謝您的回答!我已經使用extern「C」,你可以看看我的代碼:http://pastebin.archlinux.fr/464826 那麼,它是在Lisp的工作,如果我使用defparameter,不讓,所以我想這是不是C++的例外......但是我會嘗試它,我會讓你知道的。 – Filippo

+0

謝謝,它的工作原理!但只有使用Clisp,我仍然有與SBCL相同的錯誤。任何線索? – Filippo