2013-07-10 37 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