QtScript - 通过C ++实现的脚本端回调

时间:2009-11-11 01:22:59

标签: c++ qt qt4 callback

解决方案可能很简单。然后再说它可能是不可能的。

我有基本回调类:

class CFCallback {
    int command_;
    int transfer_rate_;
    public:
    CFCallback(int command, int transfer_rate = 0) {
        command_ = command; transfer_rate_ = transfer_rate; }
    virtual ~CFCallback() {}
    virtual void operator()(void *data) = 0;
    int GetCommand() { return command_; }
    int GetTransferRate() { return transfer_rate_; }
};

这是从CFCallback派生的一个例子:

void CFPacketVersion::InitiateVersion() {
    class InitiateVersionCB : public CFCallback {
        CFPacketVersion *visitor_;
        public:
        InitiateVersionCB(CFPacketVersion *v, int command) :
            CFCallback(command) {
            visitor_ = v;
        }
        void operator()(void *data) {
            Packet *pkt = (Packet *)data;
            unsigned char *pkt_data = pkt->GetData();
            std::string version = "";
            for(unsigned int i = 0; i < pkt->GetDataLength(); i++ )
                version+= pkt_data[i];
            delete []pkt_data;
            boost::regex rex("CFA(.*?):h(.*?),v(.*?)$");
            boost::smatch what;
            if( boost::regex_match(version, what, rex) ) {
                if(visitor_->GetModel()->GetName() != what[1].str() )
                    LCDInfo("Crystalfontz: Model mismatch");
                visitor_->SetHardwareVersion(what[2]);
                visitor_->SetFirmwareVersion(what[3]);
            }
        }
    };
    GetVersion(new InitiateVersionCB(this, 1));
}

GetVersion(CFCallback *)被提供给脚本引擎。

我希望能够做到InitiateVersion中看到的相同的事情,但是在javascript方面。这可能吗?

我知道我需要为CFCallback注册元类型信息。但我不知道是否可以使用指向CFCallback的指针。我最初尝试的不起作用。

另外,看作CFCallback是一个仿函数,我不确定如何将其转换为javascript。我想我可以使CFCallback成为QObject并提供operator()发出的信号。如果您有任何提示,请分享。

1 个答案:

答案 0 :(得分:2)

我担心它不会像你设置的那样起作用。

如果您希望能够在javascript中创建回调,则需要一个具有可访问GetVersion(QScriptValue)的QObject,该脚本将用于传递基于脚本的回调实现。但请注意,回调将无法使用无类型(void *)数据 - 您需要传递一个有效的QtScript对象或带有适当接口的QObject(如示例中的Packet one!)

然后你可以把它包起来:

QtScript:

function mycb(packet) {
  var pkt_data = packet.getData(); // pkt_data is probably a String or custom object with proper interface so to simplify things get the version as string
  var version = pkt_data.toString();
  pkt_data.release(); // to simulate delete [] pkt_data; this is part of custom interface
  // proceed further with the regex checks

}

GetVersion(mycb); // implies that you define the GetVersion() as a property of the global object

C ++:

QScriptValue getVersion(QScriptContext *ctx, QScriptEngine *engine)
{
 void *data = ...;
 Packet pkt_data = wrapPacketData(data);
 // Packet is interface registered with QtScript or inherits QObject
 // it has methods getData(), toString() and release()
 QScriptValueList args;
 QScriptValue pkt_data_param = engine->newQObject(&pkt_data);
 args << pkt_data_param;
 QScriptValue cb = ctx->argument(0); 
 Q_ASSERT(cb.isFunction()); // we expect a function object!
 cb.call(QScriptValue(), args);
}
QScriptValue getVersionFun = engine->newFunction(getVersion);
engine->globalObject().setProperty(QLatin1String("GetVersion"), getVersionFun);