1

Smoke は、Qt フレームワークにイントロスペクティブ C++ API ラッパーを提供します。
https://techbase.kde.org/Development/Languages/Smoke
https://techbase.kde.org/Development/Languages/Smoke/API_Documentation

SmokeC は、Smoke ラッパーを C 関数でラップして、C からの Smoke API の使用を容易にします。
https://github.com/pankajp/pysmoke/blob/master/smokec/smokec.cpp

C で動作するサンプル アプリケーション (上記の最初のリンクの C++ の例と機能的に同じ):
https://github.com/pankajp/pysmoke/blob/master/examples/helloidget.c

このサンプル アプリケーションを変更して、オブジェクト メソッドへの呼び出しをさらに追加しようとしていますが、 などQWidgetの引数を取るメソッドを呼び出す方法がわかりません。QStringsetWindowTitle

void setWindowTitle(const QString &);

これが私の最善の推測です:

/* Set the window title... Segfaults */    
methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowTitle$");
klass = Smoke_classes(classId.smoke)[classId.index];
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
stack[1].s_voidp = (void*)"hello universe";
(*klass.classFn)(meth.method, widget, stack);

...しかし、これはセグメンテーション違反です。QStringSmokeCラッパーを使用して引数を作成する方法を教えてもらえますか?

私の完全な修正済みサンプル アプリケーションは次のとおりです。

/* 
 * File:   hellowidget.c
 * Author: pankaj
 *
 * Created on November 19, 2013, 2:41 PM
 */


#include <stdio.h>
#include <string.h>
#include "smokec.h"
#include "bindings.h"


/*
 * In a bindings runtime, this should return the classname as used
 * in the bindings language, e.g. Qt::Widget in Ruby or
 * Qyoto.QWidget in C# or QtGui.QWidget in python
 */
char *className(CSmokeBinding binding, Index classId) {
    return (char*) Smoke_classes(CSmoke_FromBinding(binding))[classId].className;
}


void deleted(CSmokeBinding binding, Index classId, void *obj) 
{
}

cbool callMethod(CSmokeBinding binding, Index method, void *obj, Stack args, cbool isAbstract)
{
    return 0;
}


int main(int argc, char **argv)
{
    /* Initialize the Qt SMOKE runtime. */
    init_qtcore_CSmoke();
    init_qtgui_CSmoke();

    CSmoke qtcore_smoke = qtcore_CSmoke();
    CSmoke qtgui_smoke = qtgui_CSmoke();

    /* Create a SmokeBinding for the Qt SMOKE runtime. */
    CSmokeBinding qtcoreBinding = SmokeBinding_new(qtcore_smoke, deleted, callMethod, className);
    CSmokeBinding qtguiBinding = SmokeBinding_new(qtgui_smoke, deleted, callMethod, className);

    /* Find the 'QApplication' class. */
    CModuleIndex classId = findClass("QApplication");
    /* find the methodId. we use a munged method signature, where
     * $ is a plain scalar
     * # is an object
     * ? is a non-scalar (reference to array or hash, undef) */
    CModuleIndex methId = Smoke_findMethod(classId.smoke, "QApplication", "QApplication$?");  // find the constructor

    /* Get the Smoke::Class */
    Class klass = Smoke_classes(classId.smoke)[classId.index];

    // findMethod() returns an index into methodMaps, which has
    // information about the classId, methodNameId and methodId. we
    // are interested in the methodId to get a Smoke::Method
    Method meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];

    StackItem stack[3];
    // QApplication expects a reference to argc, so we pass it as a pointer
    stack[1].s_voidp = &argc;
    stack[2].s_voidp = argv;
    // call the constructor, Smoke::Method::method is the methodId
    // specifically for this class.
    (*klass.classFn)(meth.method, 0, stack);

    // the zeroth element contains the return value, in this case the
    // QApplication instance
    void *qapp = stack[0].s_voidp;

    // method index 0 is always "set smoke binding" - needed for
    // virtual method callbacks etc.
    stack[1].s_voidp = qtguiBinding.binding;
    (*klass.classFn)(0, qapp, stack);



    // create a widget
    classId = findClass("QWidget");
    methId = Smoke_findMethod(classId.smoke, "QWidget", "QWidget");

    klass = Smoke_classes(classId.smoke)[classId.index];
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    (*klass.classFn)(meth.method, 0, stack);

    void *widget = stack[0].s_voidp;
    // set the smoke binding
    stack[1].s_voidp = qtguiBinding.binding;
    (*klass.classFn)(0, widget, stack);

    /* Show the widget maximized.*/
    methId = Smoke_findMethod(classId.smoke, "QWidget", "showMaximized");
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    (*klass.classFn)(meth.method, widget, 0);

    /* Raise the window to the foreground */
    methId = Smoke_findMethod(classId.smoke, "QWidget", "raise");
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    (*klass.classFn)(meth.method, widget, 0);

    /* Set the modified indicator. */
    methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowModified$");
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    stack[1].s_bool = 1;
    (*klass.classFn)(meth.method, widget, stack);

    /* Set the window title... Segfaults */    
    methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowTitle$");
    klass = Smoke_classes(classId.smoke)[classId.index];
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    stack[1].s_voidp = (void*)"hello universe";
    (*klass.classFn)(meth.method, widget, stack);


    // we don't even need findClass() when we use the classId provided
    // by the MethodMap
    methId = Smoke_findMethod(qtgui_smoke, "QApplication", "exec");

    klass = Smoke_classes(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].classId];
    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];

    // call QApplication::exec()
    (*klass.classFn)(meth.method, 0, stack);

    // store the return value of QApplication::exec()
    int retval = stack[0].s_int;

    // destroy the QApplication instance
    methId = Smoke_findMethod(qtgui_smoke, "QApplication", "~QApplication");

    meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
    (*klass.classFn)(meth.method, qapp, 0);

    // destroy the smoke instance
    CSmoke_delete(qtgui_smoke);
    CSmoke_delete(qtcore_smoke);

    // return the previously stored value
    return retval;
}
4

0 に答える 0