6

Lisp から Qt ウィンドウをすばやく作成するために、おもちゃの C++ ライブラリを作成しました。common-qt が存在することは知っていますが、cffi の使用方法を学ぼうとしています。

現在、バインドされた関数が 4 つあります。

  • create-application : QApplication を作成し、ポインタを返します
  • create-window : QMainWindow を作成し、ポインタを返します
  • show : 引数として指定されたウィンドウを表示します
  • exec : Qt exec 関数

完全に動作する 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_applicationスタックに割り当てられvます。後続のコード (つまり、letバインディング) はそれを上書きします。

  2. argv終了する必要がありますNULL。つまり、要素を含める必要がargc+1あります。最後の要素は NULL です。(Qt はこれを使用していないようですが、仕様に従ってコードを記述することは良い習慣です)。

あなたの場合、スタック割り当てが問題です -letバインディングがスタック上の値を上書きし、vSBCL をクラッシュさせているようです。mallocまたはを使用してヒープnewに割り当てると、この問題が修正されます。argv

于 2013-07-13T07:08:32.860 に答える