Имеется несколько классов, обернутых для QtScript. Обернуты однотипно, вот пример одного из них
#ifndef XMLITEMOBJECT_H
#define XMLITEMOBJECT_H
////////////////////////////////////////////////////////////////
#include <QtCore/QtCore>
#include <QtXmlPatterns/QtXmlPatterns>
#include <QtScript/QtScript>
////////////////////////////////////////////////////////////////
class xmlItemObject : public QObject, public QScriptable
{
Q_OBJECT
////////////////////////////////////////////////////////////////
public:
xmlItemObject(QObject *_parent = NULL);
////////////////////////////////////////////////////////////////
signals:
////////////////////////////////////////////////////////////////
public slots:
bool isNull();
bool isNode();
////////////////////////////////////////////////////////////////
};
#endif // XMLITEMOBJECT_H
#include "xmlitemobject.h"
////////////////////////////////////////////////////////////////
Q_DECLARE_METATYPE(QXmlItem*)
////////////////////////////////////////////////////////////////
xmlItemObject::xmlItemObject(QObject *_parent) :
QObject(_parent)
{
}
////////////////////////////////////////////////////////////////
bool xmlItemObject::isNull()
{
QXmlItem *tmp = qScriptValueToValue<QXmlItem*>(this->thisObject());
return tmp->isNull();
}
////////////////////////////////////////////////////////////////
bool xmlItemObject::isNode()
{
QXmlItem *tmp = qScriptValueToValue<QXmlItem*>(this->thisObject());
return tmp->isNode();
}
////////////////////////////////////////////////////////////////
Вот класс, в котором создаются констукторы для дижка
#ifndef JSOBJECT_H
#define JSOBJECT_H
////////////////////////////////////////////////////////////////
#include <QtCore/QtCore>
#include <QtXml/QtXml>
#include <QtXmlPatterns/QtXmlPatterns>
#include <QtScript/QtScript>
#include "xmlqueryobject.h"
#include "xmlitemobject.h"
#include "xmlresultitemsobject.h"
#include "dbobject.h"
#include "sqlqueryobject.h"
////////////////////////////////////////////////////////////////
class jsObject : public QObject
{
Q_OBJECT
////////////////////////////////////////////////////////////////
QScriptEngine* jsEngine;
static QScriptValue newDbObject(QScriptContext *_context, QScriptEngine *_engine);
static QScriptValue newXmlItemObject(QScriptContext *_context, QScriptEngine *_engine);
static QScriptValue newXmlQueryObject(QScriptContext *_context, QScriptEngine *_engine);
static QScriptValue newXmlResultItemsObject(QScriptContext *_context, QScriptEngine *_engine);
////////////////////////////////////////////////////////////////
public:
explicit jsObject(QScriptEngine* _jsEngine, QObject *_parent = 0);
////////////////////////////////////////////////////////////////
signals:
////////////////////////////////////////////////////////////////
public slots:
////////////////////////////////////////////////////////////////
};
#endif // JSOBJECT_H
#include "jsobject.h"
////////////////////////////////////////////////////////////////
Q_DECLARE_METATYPE(QSqlDatabase*)
Q_DECLARE_METATYPE(QXmlItem*)
Q_DECLARE_METATYPE(QXmlQuery*)
Q_DECLARE_METATYPE(QXmlResultItems*)
////////////////////////////////////////////////////////////////
jsObject::jsObject(QScriptEngine *_jsEngine, QObject *_parent) :
QObject(_parent)
{
this->jsEngine = _jsEngine;
QScriptValue dbO(this->jsEngine->newQObject(new dbObject, QScriptEngine::ScriptOwnership));
this->jsEngine->setDefaultPrototype(qMetaTypeId<QSqlDatabase*>(), dbO);
QScriptValue dbOConstructor = this->jsEngine->newFunction(newDbObject, dbO);
this->jsEngine->globalObject().setProperty("dbObject", dbOConstructor);
QScriptValue xmlItemO(this->jsEngine->newQObject(new xmlItemObject, QScriptEngine::ScriptOwnership));
this->jsEngine->setDefaultPrototype(qMetaTypeId<QXmlItem*>(), xmlItemO);
QScriptValue xmlItemOConstructor = this->jsEngine->newFunction(newXmlItemObject, xmlItemO);
this->jsEngine->globalObject().setProperty("xmlItemObject", xmlItemOConstructor);
QScriptValue xmlQueryO(this->jsEngine->newQObject(new xmlQueryObject, QScriptEngine::ScriptOwnership));
this->jsEngine->setDefaultPrototype(qMetaTypeId<QXmlQuery*>(), xmlQueryO);
QScriptValue xmlQueryOConstructor = this->jsEngine->newFunction(newXmlQueryObject, xmlQueryO);
this->jsEngine->globalObject().setProperty("xmlQueryObject", xmlQueryOConstructor);
QScriptValue xmlResultItemsO(this->jsEngine->newQObject(new xmlResultItemsObject, QScriptEngine::ScriptOwnership));
this->jsEngine->setDefaultPrototype(qMetaTypeId<QXmlResultItems*>(), xmlResultItemsO);
QScriptValue xmlResultItemsOConstructor = this->jsEngine->newFunction(newXmlResultItemsObject, xmlResultItemsO);
this->jsEngine->globalObject().setProperty("xmlResultItemsObject", xmlResultItemsOConstructor);
}
////////////////////////////////////////////////////////////////
QScriptValue jsObject::newDbObject(QScriptContext *_context, QScriptEngine *_engine)
{
QSqlDatabase* db = new QSqlDatabase(QSqlDatabase::addDatabase(qScriptValueToValue<QString>(_context->argument(0)),
qScriptValueToValue<QString>(_context->argument(1))
));
db->setDatabaseName(qScriptValueToValue<QString>(_context->argument(2)));
return qScriptValueFromValue<QSqlDatabase*>(_engine, db);
}
////////////////////////////////////////////////////////////////
QScriptValue jsObject::newXmlQueryObject(QScriptContext *_context, QScriptEngine *_engine)
{
QXmlQuery* xmlQuery = new QXmlQuery;
return qScriptValueFromValue<QXmlQuery*>(_engine, xmlQuery);
}
////////////////////////////////////////////////////////////////
QScriptValue jsObject::newXmlItemObject(QScriptContext *_context, QScriptEngine *_engine)
{
QXmlItem* xmlItem = qScriptValueToValue<QXmlItem*>(_context->argument(0));
return qScriptValueFromValue<QXmlItem*>(_engine, xmlItem);
}
////////////////////////////////////////////////////////////////
QScriptValue jsObject::newXmlResultItemsObject(QScriptContext *_context, QScriptEngine *_engine)
{
QXmlResultItems* xmlResultItems = new QXmlResultItems;
return qScriptValueFromValue<QXmlResultItems*>(_engine, xmlResultItems);
}
////////////////////////////////////////////////////////////////
Вот класс с параметрами, передаваемыми в скрипт
#ifndef WORKSCRIPTPARAM_H
#define WORKSCRIPTPARAM_H
////////////////////////////////////////////////////////////////
#include <QtCore/QtCore>
#include <QtScript/QtScript>
#include <QtSql/QtSql>
#include <QtXmlPatterns/QtXmlPatterns>
#include "xmlqueryobject.h"
#include "xmlresultitemsobject.h"
#include "dbobject.h"
////////////////////////////////////////////////////////////////
class workScriptParam : public QObject
{
Q_OBJECT
////////////////////////////////////////////////////////////////
QString message;
QString typeValue;
QString actionValue;
QXmlResultItems* itemsData;
QXmlQuery* xmlQuery;
QSqlDatabase* db;
////////////////////////////////////////////////////////////////
public:
explicit workScriptParam(const QString &_message,
const QString &_typeValue,
const QString &_actionValue,
QXmlResultItems *_itemsData,
QXmlQuery *_xmlQuery,
QSqlDatabase *_db,
QObject *_parent = NULL
);
~workScriptParam();
////////////////////////////////////////////////////////////////
signals:
void sendMessageSignal(QString* _mess);
////////////////////////////////////////////////////////////////
public slots:
QString getMessage();
QString getTypeMessage();
QString getActionMessage();
QXmlQuery* getXmlQuery();
QXmlResultItems* getItemsData();
QSqlDatabase* getDb();
void sendMessage(QString _mess);
////////////////////////////////////////////////////////////////
};
#endif // WORKSCRIPTPARAM_H
#include "workscriptparam.h"
////////////////////////////////////////////////////////////////
workScriptParam::workScriptParam(const QString &_message,
const QString &_typeValue,
const QString &_actionValue,
QXmlResultItems *_itemsData,
QXmlQuery *_xmlQuery,
QSqlDatabase *_db,
QObject *_parent
) :
QObject(_parent)
{
this->message = _message;
this->typeValue = _typeValue;
this->actionValue = _actionValue;
this->itemsData = _itemsData;
this->xmlQuery = _xmlQuery;
this->db = _db;
}
////////////////////////////////////////////////////////////////
workScriptParam::~workScriptParam()
{
}
////////////////////////////////////////////////////////////////
QString workScriptParam::getMessage()
{
return this->message;
}
////////////////////////////////////////////////////////////////
QString workScriptParam::getTypeMessage()
{
return this->typeValue;
}
////////////////////////////////////////////////////////////////
QString workScriptParam::getActionMessage()
{
return this->actionValue;
}
////////////////////////////////////////////////////////////////
QXmlQuery *workScriptParam::getXmlQuery()
{
return this->xmlQuery;
}
////////////////////////////////////////////////////////////////
QXmlResultItems *workScriptParam::getItemsData()
{
return this->itemsData;
}
////////////////////////////////////////////////////////////////
QSqlDatabase* workScriptParam::getDb()
{
return this->db;
}
////////////////////////////////////////////////////////////////
void workScriptParam::sendMessage(QString _mess)
{
QString* tmpMes = new QString(_mess);
emit this->sendMessageSignal(tmpMes);
}
////////////////////////////////////////////////////////////////
Вот скрипт
if(param.getTypeMessage() === 'QUERY' && param.getActionMessage() === 'TASK')
{
var db = param.getDb();
var xmlQuery = param.getXmlQuery();
var itemsData = param.getItemsData();
var item = itemsData.next();
while(!item.isNull())
{
if(item.isNode())
{
xmlQuery.setFocus(item);
xmlQuery.setQuery("./actionsTask/actionTask");
if(!xmlQuery.isValid())
{
print('ERROR((');
return;
}
var itemsActionTask = new xmlResultItemsObject();
xmlQuery.evaluateTo(itemsActionTask);
var itemActionTask = itemsActionTask.next();
var actions = [];
while (!itemActionTask.isNull())
{
if(itemActionTask.isNode())
{
xmlQuery.setFocus(itemActionTask);
xmlQuery.setQuery("./string()");
if(!xmlQuery.isValid())
{
print('ERROR(=');
return;
}
var action = xmlQuery.evaluateTo();
print(action);
actions.push(action);
}
itemActionTask = itemsActionTask.next();
}
print(actions);
}
item = itemsData.next();
}
if(db.transaction())
{
if(!db.commit())
{
print('error commit()');
}
}
else
{
print('error transaction()');
if(!db.rollback())
{
print('error rollback()');
}
}
}
Вот он вызывается
workScriptParam *p = new workScriptParam(*_mess,
typeValue,
actionValue,
itemsData,
xmlQuery,
&this->db
);
this->connect(p, SIGNAL(sendMessageSignal(QString*)), this, SLOT(sendMessageSlot(QString*)));
QScriptEngine* jsEngine = new QScriptEngine;
jsObject *jsO = new jsObject(jsEngine);
QFile file(this->pathWorkScript);
file.open(QIODevice::ReadOnly);
QScriptValue param = jsEngine->newQObject(p, QScriptEngine::ScriptOwnership);
jsEngine->globalObject().setProperty("param", param);
QScriptValue res = jsEngine->evaluate(file.readAll());
if(res.isError())
{
output::printError(QString("Script \"%1\" is error %2").arg(this->pathWorkScript).arg(res.toString()).toStdWString().c_str(), __FILEW__, __LINE__);
throw;
}
file.close();
delete xmlQuery;
delete itemsData;
delete p;
delete jsO;
delete jsEngine;
Данный вызов происходит несколько 10-в раз в секунду, память постоянно растет. Что я не так делаю? Почему объекты не удаляются? Утечка именно в скрипте, потому что если его вызов убрать все нормально.