qt — вызывать экземпляр объекта из функции C ++, вызываемой через скрипт

У меня есть класс с именем Jellyfish, который использует шаблон проектирования Singleton:

jellyfish.h

#ifndef JELLYFISH_H
#define JELLYFISH_H

#include <QHash>
#include <QScriptEngine>

class QScriptValue;

class Jellyfish : public QObject
{

public:

static Jellyfish * getInstance();
static Jellyfish * instance;

private:

Jellyfish();

};

#ifndef

jellyfish.cpp

Jellyfish * Jellyfish::instance = NULL;

Jellyfish * Jellyfish::getInstance()
{

if ( !Jellyfish::instance )
{
Jellyfish::instance = new Jellyfish();
}

return Jellyfish::instance;

}

Когда я нахожусь в main.cpp и делаю тесты, у меня нет ошибок:

main.cpp

#include <QApplication>

#include "jellyfish.h"
class Jellyfish;

int main( int argc, char *argv[] )
{

QApplication app( argc, argv );

Jellyfish *toto = Jellyfish::getInstance();
Jellyfish *toto2 = Jellyfish::getInstance();
Jellyfish *toto3 = Jellyfish::getInstance();

return app.exec();

}

Но я хочу использовать некоторые статические методы в Jellyfish во внешних файлах QScript:

jellyfish.h

private:

static QScriptValue set( QScriptContext *context, QScriptEngine *engine );
QScriptEngine *script_engine;

jellyfish.cpp

Jellyfish::Jellyfish()
{

script_engine = new QScriptEngine;

/* ... */

initScriptEngine();

}

void Jellyfish::initScriptEngine()
{

QScriptValue object = script_engine->newQObject( this );

object.setProperty( "set", script_engine->newFunction( set ) );

script_engine->globalObject().setProperty( "jellyfish", object );

}

QScriptValue Jellyfish::set( QScriptContext *context, QScriptEngine *engine )
{

// I have to load instance because I am in a static method.
// But this is where the application loop endlessly.
Jellyfish *jellyfish = Jellyfish::getInstance();
return true;

}

И наконец разобрали скрипт:

jellyfish.set( "line_numbers",  true );

проблема

Когда я запускаю приложение, getInstance() всегда создает новый экземпляр Медузы. Но настоящая проблема в том, что на выходе с отладкой (qDebug() << "test";) Я вижу, что цикл приложения на Jellyfish::getInstance(); пока я не получу sgmentation fault,

Может ли кто-нибудь помочь мне понять это?

1

Решение

Это потому, что ваш конструктор Jellyfish вызывает себя рекурсивно!

Сломайте вашу программу в отладчике, и вы увидите обратную трассировку:

   ...
Jellyfish::Jellyfish()
Jellyfish::getInstance()
Jellyfish::set
Jellyfish::initScriptEngine()
Jellyfish::Jellyfish()
Jellyfish::getInstance()

Проблема в том, что ваш конструктор вызывает Jellyfish::getInstance(), но когда объект построен Jellyfish::instance все еще NULL:

Jellyfish * Jellyfish::getInstance()
{

if ( !Jellyfish::instance )
{
// this line
// Jellyfish::instance = new Jellyfish();
// is equivalent to
Jellyfish * temp = new Jellyfish(); // *
Jellyfish::instance = temp; // not NULL after construction
}

return Jellyfish::instance;

}

Если вы вызываете getInstance () из своего конструктора, то это всегда приведет к бесконечной рекурсии (до сегфоута). Единственное решение — вызвать Jellyfish :: initScriptEngine () не из вашего конструктора, а явно:

   Jellyfish::getInstance()->initScriptEngine();
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]