6

我已经构建了一些玩具 C++ 库来从 Lisp 快速创建一个 Qt 窗口。我知道 common-qt 存在,我只是想学习如何使用 cffi。

现在,我有 4 个绑定函数:

  • create-application :创建一个 QApplication 并返回一个指针
  • create-window : 创建一个 QMainWindow 并返回一个指针
  • show :显示指定为参数的窗口
  • exec : Qt 执行函数

这是一个完美运行的 lisp 代码:

(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*...我有内存错误!

(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

谢谢。

4

1 回答 1

2

我建议您执行以下操作:

  1. 由于您正在编写库 C++ 并使用 Lisp 中的符号,因此请确保使用extern "C"声明 - 需要这些声明以确保 C++ 编译器不会破坏名称。

  2. 检查您的库是否在 C(不是 C++)应用程序中工作。这将确保库本身正常工作(例如,它不会抛出 C++ 异常)。

升级版:

我试图运行你的代码并且遇到了同样的崩溃。问题似乎出在您的create_application功能上。我在http://paste.lisp.org/display/138049附上了我的这个函数的固定版本。

具体来说有2个问题:

  1. create_applicationv在堆栈上分配。随后的代码(即let绑定)会覆盖它。

  2. argv应该NULL终止。即,它应该包含argc+1元素——最后一个元素是NULL。(Qt好像不用这个,但是按照规范写代码是个好习惯)。

在您的情况下,堆栈分配是问题所在 - 绑定似乎let覆盖了v堆栈上的值,导致 SBCL 崩溃。使用malloc或在堆上new分配可解决此问题。argv

于 2013-07-13T07:08:32.860 回答