Russian Qt Forum

Qt => Qt Script, QtWebKit => Тема начата: freebsdd от Декабрь 01, 2015, 21:45



Название: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 01, 2015, 21:45
Здравствуйте!

Вопрос такой, бьюсь уже не первую пару тройку часов

Создал библиотеку:

Код:

class CALCSHARED_EXPORT Calc : public QObject
{
    Q_OBJECT
    public:
        Calc(QObject* pwgt) : QObject(pwgt){
            qDebug() << "[DLL]::CREATE";
            QScriptEngine *sh_engine = new QScriptEngine(this);
            qDebug() << "the magic number is:" << sh_engine->evaluate("1 + 2").toNumber();
        }
};


вызываю из приложения (в приложении создаётся поток из него вызывается, не знаю важно ли это):

Код:

QScriptEngine *sh_engine = new QScriptEngine(this);
qDebug() << "the magic number is:" << sh_engine->evaluate("1 + 2").toNumber();


Calc *s_calc = new Calc(this);


В самом приложении выполняется, расчёт есть, всё хорошо, а обращаясь к библиотеке, не выполняется, пишет:


QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine


Пробовал вместо this, pwgt, вроде как дочерний создаётся, но эффект тот же


Пробовал создать ядро: QCoreApplication a(argc1, argv1), рассчиталось, показало цифру 3 и вылетело приложение


Добавил " : public QObject", убрал создание QCoreApplication, пишет, что не может создать дочку...

QObject: Cannot create children for a parent that is in a different thread.
(Parent is sh_worker_sheds(0x427fa8), parent's thread is QThread(0x418b60), current thread is QThread(0x3a55e0)




Подскажите пожалуйста, как в самой библиотеке можно использовать класс QScriptEngine, нужно именно в библиотеке, т.к. именно через неё все расчёты будут вестись
 
 


Название: Re: QScriptEngine в dll
Отправлено: Bepec от Декабрь 02, 2015, 08:30
Ну, тут вопросы уточняющие - dll используется в программе, написанной не на Qt? Походу да :)
Тогда вам нужно самому запускать луп евент событий, или в просторечии QCoreApplication в потоке dll.

Подробности по ссылке http://qtsimple.blogspot.ru/2013/10/dll-noqt.html, задавать вопросы можете тут.

PS и напоминаю, писана эта статья для одной (1) длл подгружаемой в программе. При множественной загрузке возможны проблемы, там ещё допиливать надо было, но я не стал :)


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 09:33
вызываю из приложения (в приложении создаётся поток из него вызывается, не знаю важно ли это):
Действуют обычные правила, а где сидит вызываемый, в dll или нет - без разницы

В самом приложении выполняется, расчёт есть, всё хорошо, а обращаясь к библиотеке, не выполняется, пишет:


QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine
Ну да, это нормально, многие Qt классы требуют чтобы QApplication был создан. Не понял с чем Вы так отчаянно бьетесь, чего хотите добиться? На то и библиотека чтобы вызываться из приложения. Да, сначала приложение должно создать QApplication, а потом уже обратиться к библиотеке, тогда она сможет создавать экземпляры нужных классов. А создавать QApplication в библиотеке смысла нет.   


Название: Re: QScriptEngine в dll
Отправлено: Bepec от Декабрь 02, 2015, 09:49
псс, igors окститесь :) Есть такая тема, как использование Qt dll в noQt приложениях.

PS хотя кому я это говорю :D


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 10:13
Ну, тут вопросы уточняющие - dll используется в программе, написанной не на Qt? Походу да :)
Тогда вам нужно самому запускать луп евент событий, или в просторечии QCoreApplication в потоке dll.

Подробности по ссылке http://qtsimple.blogspot.ru/2013/10/dll-noqt.html, задавать вопросы можете тут.

PS и напоминаю, писана эта статья для одной (1) длл подгружаемой в программе. При множественной загрузке возможны проблемы, там ещё допиливать надо было, но я не стал :)

У меня и библиотека и приложение, всё написано на Qt 5.5. Библиотеку я думаю использовать, в своих приложениях пока только на Qt. Как в таком случае действовать, как запихнуть QScriptEngine в dll и вызывая функцию\процедуру из приложения, чтоб она работала\считала?


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 10:17
вызываю из приложения (в приложении создаётся поток из него вызывается, не знаю важно ли это):
Действуют обычные правила, а где сидит вызываемый, в dll или нет - без разницы

В самом приложении выполняется, расчёт есть, всё хорошо, а обращаясь к библиотеке, не выполняется, пишет:


QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine
Ну да, это нормально, многие Qt классы требуют чтобы QApplication был создан. Не понял с чем Вы так отчаянно бьетесь, чего хотите добиться? На то и библиотека чтобы вызываться из приложения. Да, сначала приложение должно создать QApplication, а потом уже обратиться к библиотеке, тогда она сможет создавать экземпляры нужных классов. А создавать QApplication в библиотеке смысла нет.   

Смысла то нет, пробовал уже всё что можно, но как сделать, что она работала, не могу понять, в тупик зашёл, как можно сделать реализацию?


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 10:25
Есть такая тема, как использование Qt dll в noQt приложениях.
Какое же здесь "noQt"?

Смысла то нет, пробовал уже всё что можно, но как сделать, что она работала, не могу понять, в тупик зашёл, как можно сделать реализацию?
Ну просто в приложении сначала создать QApplication, а потом уже вызывать ф-ции/классы dll.


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 11:07
Есть такая тема, как использование Qt dll в noQt приложениях.
Какое же здесь "noQt"?

Смысла то нет, пробовал уже всё что можно, но как сделать, что она работала, не могу понять, в тупик зашёл, как можно сделать реализацию?
Ну просто в приложении сначала создать QApplication, а потом уже вызывать ф-ции/классы dll.

Уточню, у меня: Консольное приложение -> создаётся основной поток -> создаются потоки с таймером в потоке(для каждой задачи свой) -> (в дочернем потоке, а именно в слоте по сигналу timeout()) выполняется функция из dll для расчёта арифметического - и вот она, не работает, хотя в этом же потоке (не обращаясь в библиотеку) выполняется QScriptEngine без проблем... У меня же уже есть QCoreApplication, для чего ещё раз создавать или я Вас не понял?


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 11:58
У меня же уже есть QCoreApplication, для чего ещё раз создавать или я Вас не понял?
Создавать второй раз нельзя. Значит у Вас криво собрана dll. Распечатайте qApp из приложения и из dll и убедитесь что они равны (после создания QApplication). Убедитесь что приложение и dll используют одну и ту же QtCore


Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 02, 2015, 12:02
А нет ли статической инициализации в dll, в которой и создаётся QScriptEngine?

В любом случае не мешало бы в отладчике поставить breakpoint на создании QScriptEngine и посмотреть backtrace всех ниток.


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 12:42
У меня же уже есть QCoreApplication, для чего ещё раз создавать или я Вас не понял?
Создавать второй раз нельзя. Значит у Вас криво собрана dll. Распечатайте qApp из приложения и из dll и убедитесь что они равны (после создания QApplication). Убедитесь что приложение и dll используют одну и ту же QtCore

Скажите, что такое "распечатайте qApp" ?


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 12:47
Скажите, что такое "распечатайте qApp" ?
Код
C++ (Qt)
qDebug() << qApp;


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 12:53
А нет ли статической инициализации в dll, в которой и создаётся QScriptEngine?

В любом случае не мешало бы в отладчике поставить breakpoint на создании QScriptEngine и посмотреть backtrace всех ниток.


Мне стыдно, но отладчик не настраивал, пока не разбирался как установить его на QtCreator... Гляньте код, пожалуйста:


calc.h
Код:
#ifndef CALC_H
#define CALC_H

#include "calc_global.h"
#include <QObject>
//#include <QScriptEngine>
//#include <qDebug>

//class CALCSHARED_EXPORT Calc
//{

//    public:
//        Calc();
//};

class CALCSHARED_EXPORT Calc : public QObject {
    Q_OBJECT
    public:
        Calc(QObject *parent = 0);
};

#endif // CALC_H


calc_global.h
Код:
#ifndef CALC_GLOBAL_H
#define CALC_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(CALC_LIBRARY)
#  define CALCSHARED_EXPORT Q_DECL_EXPORT
#else
#  define CALCSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // CALC_GLOBAL_H


calc.cpp
Код:
#include "calc.h"
#include <QScriptEngine>
#include <qDebug>


Calc::Calc(QObject *parent) : QObject(parent){

    QScriptEngine *ml = new QScriptEngine(this);
    qDebug() << ml->evaluate("1+2+5").toNumber();

}


Создал для теста приложение GUI, от туда пытаюсь запустить:
Код:
void MainWindow::on_pushButton_3_clicked()
{
    Calc *mc = new Calc(this);

}


Ошибка, вернее две:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x17fea4), parent's thread is QThread(0x376028), current thread is QThread(0x3d0bf8)

QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine



Вроде всё хорошо, Есть Приложение, создаю дочку CALC , не может, почему? Что я не так делаю?

Бывает под носом ответ, но видать глаз мылиться, не вижу...


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 13:01
Скажите, что такое "распечатайте qApp" ?
Код
C++ (Qt)
qDebug() << qApp;

Благодарю за способ, сделал, интересный результат:

Код снизу, для наглядности, чтоб не листать страницу вверх\вниз... Туда добавил qDebug():

Gui:
Код:
void MainWindow::on_pushButton_3_clicked()
{
    qDebug() << "this: " << this;
    Calc *mc = new Calc(this);

}


calc.h
Код:
#ifndef CALC_H
#define CALC_H

#include "calc_global.h"
#include <QObject>

class CALCSHARED_EXPORT Calc : public QObject {
    Q_OBJECT
    public:
        Calc(QObject *parent = 0);
};

#endif // CALC_H

calc.cpp
Код:
#include "calc.h"
#include <QScriptEngine>
#include <qDebug>


Calc::Calc(QObject *parent) : QObject(parent){

    qDebug() << "parent: " << parent;
    qDebug() << "this: " << this;

    QScriptEngine *ml = new QScriptEngine(this);
    qDebug() << ml->evaluate("1+2+5").toNumber();

}


Результат:

GUI: this:  MainWindow(0x24fea0, name = "MainWindow")
Calc: QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x24fea0), parent's thread is QThread(0x2c6028), current thread is QThread(0x326378)

Calc: parent:  MainWindow(0x24fea0, name = "MainWindow")

Calc: this:  Calc(0x323fd8)

Calc: QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine


Т.е. папаню видит, в библиотеку дескриптор передаётся, но почему тогда не создаётся QScriptEngine?




Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 02, 2015, 13:02
Мне стыдно, но отладчик не настраивал, пока не разбирался как установить его на QtCreator...
Разработка без отладки - довольно-таки странный подход...

Цитировать
Вроде всё хорошо, Есть Приложение, создаю дочку CALC , не может, почему? Что я не так делаю?
Судя по
Цитировать
QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine
приложения ещё нет


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 13:09
Мне стыдно, но отладчик не настраивал, пока не разбирался как установить его на QtCreator...
Разработка без отладки - довольно-таки странный подход...

Цитировать
Вроде всё хорошо, Есть Приложение, создаю дочку CALC , не может, почему? Что я не так делаю?
Судя по
Цитировать
QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine
приложения ещё нет


Код:
Calc::Calc(QObject *parent) : QObject(parent){

    qDebug() << "parent: " << parent;
    <...>

qDebug() говорит, что дескриптор передан:

Calc: parent:  MainWindow(0x24fea0, name = "MainWindow")

Хотя вроде всё просто очень... Но может неверно передаю или делаю?


Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 02, 2015, 13:13
Причём здесь MainWindow ???
Зачем в n-ом посте пастить одно и тоже?
Сказано же, что
Цитировать
QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 13:22
Причём здесь MainWindow ???
Зачем в n-ом посте пастить одно и тоже?
Сказано же, что
Цитировать
QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine


MainWindow - это родитель, родитель в библиотеку передаётся, я про это.

Сказано то хорошо, но но так как вопрос решить с этим сообщением?


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 14:01
..но отладчик не настраивал, пока не разбирался как установить его на QtCreator...
Нет, товарищ, так дело не пойдет, без отладчика это не работа а хз что, можно и месяцами мудохаться без толку.

И не "растекайтесь мыслью по древу". Вы проверили qApp? Нет, так чего хвататься за MainWindow?


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 15:11
..но отладчик не настраивал, пока не разбирался как установить его на QtCreator...
Нет, товарищ, так дело не пойдет, без отладчика это не работа а хз что, можно и месяцами мудохаться без толку.

И не "растекайтесь мыслью по древу". Вы проверили qApp? Нет, так чего хвататься за MainWindow?

Оооо, мой глубокий пардон, я подумал Вы про дескрипторы, всё, сделал, как просили:

из GUI:
1::  QApplication(0x19fdcc)

из DLL:
2::  QObject(0x0)


Только qApp, это же указатель от созданного QApplication, как он может быть в библиотеке, там же нет его создания?


Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 02, 2015, 15:18
Только qApp, это же указатель от созданного QApplication, как он может быть в библиотеке, там же нет его создания?
Мде... как всё запущено :(
Чего с базовыми знаниями совсем беда.


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 15:26
..всё, сделал, как просили:
Как "предложили" :) Теперь проверьте что говорил Змей - может это на инициализации dll?  Какая печать выскакивает первой?

Только qApp, это же указатель от созданного QApplication, как он может быть в библиотеке, там же нет его создания?
Он и не в библиотеке, но должен быть видим для нее


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 15:42
..всё, сделал, как просили:
Как "предложили" :) Теперь проверьте что говорил Змей - может это на инициализации dll?  Какая печать выскакивает первой?

Только qApp, это же указатель от созданного QApplication, как он может быть в библиотеке, там же нет его создания?
Он и не в библиотеке, но должен быть видим для нее

Понял, хорошо, благодарю!


По печати:

При:
Calc *mc = new Calc(this);

Первое, что выходит:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x1efb70), parent's thread is QThread(0x3b5928), current thread is QThread(0x405f70)



Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 02, 2015, 16:00
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x1efb70), parent's thread is QThread(0x3b5928), current thread is QThread(0x405f70)
До этого очередь дойдет, то (предполагаю) еще одна проблема или ошибка. Но сейчас надо до конца разобраться с qApp. Вот Вы вставили 2 печати qApp - одну в приложении, сразу после создания QApplication. и вторую в dll. Какая из них первая в консоли?


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 02, 2015, 19:39
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MainWindow(0x1efb70), parent's thread is QThread(0x3b5928), current thread is QThread(0x405f70)
До этого очередь дойдет, то (предполагаю) еще одна проблема или ошибка. Но сейчас надо до конца разобраться с qApp. Вот Вы вставили 2 печати qApp - одну в приложении, сразу после создания QApplication. и вторую в dll. Какая из них первая в консоли?


Гениально! Что интересно, если прям сразу после:

QCoreApplication a(argc, argv);

и так и так:
Calc *mc = new Calc(&a);
Calc *mc = new Calc(qApp);

Обе работают, а когда создаю класс, в котором поток и в потоке выполняю

Calc *mc = new Calc(qApp);

Не работает...

Сегодня нужно уже бежать, завтра с утра продолжу, протестирую, может что упустил, обязательно напишу!



Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 03, 2015, 10:45
Гениально! Что интересно, если прям сразу после:

QCoreApplication a(argc, argv);

и так и так:
Calc *mc = new Calc(&a);
Calc *mc = new Calc(qApp);

Обе работают, а когда создаю класс, в котором поток и в потоке выполняю

Calc *mc = new Calc(qApp);

Не работает...
Т.е. то что выше уже несколько раз постилось
Цитировать
QObject: Cannot create children for a parent that is in a different thread.
нам как бы по-фигу!
Действительно Гениально!, Карл!

Для чего Calc-у вообще нужен родитель?


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 03, 2015, 13:58
Гениально! Что интересно, если прям сразу после:

QCoreApplication a(argc, argv);

и так и так:
Calc *mc = new Calc(&a);
Calc *mc = new Calc(qApp);

Обе работают, а когда создаю класс, в котором поток и в потоке выполняю

Calc *mc = new Calc(qApp);

Не работает...
Т.е. то что выше уже несколько раз постилось
Цитировать
QObject: Cannot create children for a parent that is in a different thread.
нам как бы по-фигу!
Действительно Гениально!, Карл!

Для чего Calc-у вообще нужен родитель?


Да ладно Вам издеваться... После долго поиска проблемы, когда находится решение, чувство радости и восторга. Я так не хотел парсинг свой писать - это ж велосипед на костылях (или из костылей), не люблю костыли, ужас просто, поэтому очень рад решению!!!

Несколько раз постил - объясню - код я вставил, для наглядности, например, если я скажу вот в том то коде то то или вставлю кусочек маленький кода (я ж его изменил уже), сразу видно, только из за этого.


1. Calc-у нужен родитель, чтоб не было хаоса в программе, всё от одного, создался батя, у него детишки, для управления и управлению памятью, чтоб утечки не было, прекратил работу родителя, прекратились и потомки;

2. Кстати, нашёл проблему о которой вчера я, почему у меня после QCoreApplication - выполняется, а в потоке нет, нашёл решение, но не понял, почему так,

Файл .PRO
Код:
win32: LIBS += -L$$PWD/../../dll/calc/build-Calc-Desktop_Qt_5_5_0_MSVC2012_32bit-Release/release/ -lCalc
#win32: LIBS += -L$$PWD/../../dll/calc/build-Calc-Desktop_Qt_5_5_0_MSVC2012_32bit-Debug/debug/ -lCalc

Скажите пожалуйста, когда я в режиме отладки(debug) выпускаю библиотеку, в библиотеке присутствует qApp, а когда в режиме выпуска(release) - qApp отсутствует. почему так?




Название: Re: QScriptEngine в dll
Отправлено: GreatSnake от Декабрь 03, 2015, 14:11
Скажите пожалуйста, когда я в режиме отладки(debug) выпускаю библиотеку, в библиотеке присутствует qApp, а когда в режиме выпуска(release) - qApp отсутствует. почему так?
Потому что qApp - это макрос
Код
C++ (Qt)
#define qApp QCoreApplication::instance()


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 03, 2015, 14:28
Скажите пожалуйста, когда я в режиме отладки(debug) выпускаю библиотеку, в библиотеке присутствует qApp, а когда в режиме выпуска(release) - qApp отсутствует. почему так?
Потому что qApp - это макрос
Код
C++ (Qt)
#define qApp QCoreApplication::instance()

А в итоге то какую библиотеку(*.dll) использовать в приложении в "промышленности", которая выпущена в режиме отладки или выпуска?


Название: Re: QScriptEngine в dll
Отправлено: Igors от Декабрь 03, 2015, 14:47
1. Calc-у нужен родитель, чтоб не было хаоса в программе,
Нужен так нужен, но назначая родителем QApplication Вы без нужды нарываетесь на возможные проблемы в деструкторе.  

Скажите пожалуйста, когда я в режиме отладки(debug) выпускаю библиотеку, в библиотеке присутствует qApp, а когда в режиме выпуска(release) - qApp отсутствует. почему так?
Потому что либа схватила одну QtCore, в приложение - другую. Ну и понеслась "моя твоя не понимай". Лучше давать дебажной либе др имя, обычно добавляют "d"


Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 03, 2015, 15:05
1. Calc-у нужен родитель, чтоб не было хаоса в программе,
Нужен так нужен, но назначая родителем QApplication Вы без нужды нарываетесь на возможные проблемы в деструкторе.  

Скажите пожалуйста, когда я в режиме отладки(debug) выпускаю библиотеку, в библиотеке присутствует qApp, а когда в режиме выпуска(release) - qApp отсутствует. почему так?
Потому что либа схватила одну QtCore, в приложение - другую. Ну и понеслась "моя твоя не понимай". Лучше давать дебажной либе др имя, обычно добавляют "d"

1. Возможные проблемы в деструкторе, Вы имеете ввиду с освобождение объектов проблемы?

2. Вы быть может имеете ввиду, зачем он именно мне вообще там нужен, обожаю родной язык, смотря какая интонация одного и того же предложения - смысл уже меняется. По родителю - мало ли что туда добавлю ещё, например таймер без родителя не работает, QScriptEngine без QCoreApplication не работает, передать туда родителя и она уже наделена дополнительными возможностями в будущем. Если нет нужды можно же просто ... Calc fCalc; И пользоваться другими функциями\процедурами, где нет нужды в родителе... Если я в чём то ошибаюсь пожалуйста, скажите.

3. Может я что не понимаю, а зачем 2 библиотеки выпуск и дебажная в "промышленности", если можно одну дебажную использовать?



Название: Re: QScriptEngine в dll
Отправлено: freebsdd от Декабрь 03, 2015, 15:58
Ладно, чтоб Вас не отвлекать нескончаемыми вопросами, т.к. изначальный вопрос - решён, я закрою тему.

Bepec - Благодарю за ссылку!

GreatSnake и Igors, ребята от души Благодарю Вас, что были моими учителями, Вы мне очень много знаний передали, указали на саму суть, крепко жму Ваши руки!.



Тема закрыта!