Russian Qt Forum
Ноябрь 28, 2024, 08:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Сборка мусора в QJSEngine  (Прочитано 29764 раз)
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« : Ноябрь 26, 2020, 16:52 »

Коллеги,
мне в проекте Qt требуется исполнение скриптов на JavaScript (выполнение различных настраиваемых проверок, вычисляемые переменные и т.д.). Раньше для этих задач использовал PythonQt, теперь хочу переключиться на QJSEngine. Вроде, все хорошо, но споткнулся на простой вещи - в скрипте мне нужно в качестве возвращаемого значения использовать объект моего типа, например:
Код
Javascript
var v = myObj.val(777);
v.value;
v.alarm;
 

Для этого я в C++ объявляю два класса: враппер MyObject, объект которого добавляется в проперть движка QJSEngine:
Код
C++ (Qt)
   myObj = new MyObject();
   QJSValue jmyObj = myEngine->newQObject(myObj);
   myEngine->globalObject().setProperty("myObj", jmyObj);
 
и класс возвращаемого значения MyValue, добавляемый в метаобъектную модель и в проперти движка:
Код
C++ (Qt)
   QJSValue jsMyValue = myEngine->newQMetaObject(&MyValue::staticMetaObject);
   myEngine->globalObject().setProperty("MyValue", jsMyValue);
 
Понятно, что оба класса объявляются со всей мутотой типа Q_INVOKABLE, набором конструкторов по умолчанию, копирования, оператором присваивания, регистрацией метатипов - все это можно посмотреть в присоединенном проекте.
Но вот незадача: если в том самом методе MyObject::val, который я вызываю в js, возвращается значение:
Код
C++ (Qt)
   Q_INVOKABLE MyValue val(int value) {
       return MyValue(value, true);
   }
 
то в скрипте это не работает (свойство v.value дает undefined).
Нашел в Интернете одну единственную подсказку - метод должен возвращать указатель:
Код
C++ (Qt)
   Q_INVOKABLE MyValue* val(int value) {
       return new MyValue(value, true);
   }
 
Тогда все нормально, и вышеприведенный js код работает. Но возникает сразу несколько вопросов:
1) где прочитать объяснения про то, как нужно объявлять методы с возвратом объекта пользовательского типа?
2) напрягает этот new - как избежать утечки памяти? Моя программа работает непрерывно месяцами, при этом вызовы скриптов выполняются постоянно. Сомневаюсь, что этим занимается QJSEngine - даже если использовать parent при создании MyValue, то объект MyObject живет постоянно в течение всего цикла работы программы;
3) а как вообще со сборкой мусора у QJSEngine , можно ли его вообще использовать в программах, скрипты запускаются постоянно в течение длительного времени?
Прошу прощения за пространное объяснение, но, может, кому-то пригодится...

« Последнее редактирование: Ноябрь 27, 2020, 14:16 от sergek » Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Ноябрь 27, 2020, 09:47 »

[off]
Раньше для этих задач использовал PythonQt, теперь хочу переключиться на QJSEngine.
Каковы мотивы/резоны такого перехода? Вроде пытон "солиднее". Спасибо
[/off]
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #2 : Ноябрь 27, 2020, 11:38 »

Каковы мотивы/резоны такого перехода? Вроде пытон "солиднее". Спасибо
Только один - js уже встроен в Qt, а PythonQt надо подключать к проекту, а он у меня и так разбух)) Да и не нужно мне всех его солидных возможностей - нужен доступ к данным и БД, выполнение некоторых функций, например, опрос периферийный устройств. К тому же синтаксис javascript проще и ближе к любимому C++ Улыбающийся.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #3 : Ноябрь 27, 2020, 12:19 »

Там есть сборка мусора, для старого движка была целая страница в докуметации как и когда он берет на себя удаление а когда нет. Искать лень=(
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #4 : Ноябрь 27, 2020, 13:46 »

Меня беспокоит непонимание того, как осуществляется удаление объектов, которые в коде функций C++ создаются с помощью new, а вызываются эти функции в скрипте js. Иными словами, где будет вызвано delete? В скрипте я этого не делаю, в коде C++ тоже. Матаобъектная модель? С какого перепугу?
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #5 : Ноябрь 27, 2020, 13:55 »

Ну типа если тип объекта указатель, то он вызывает деструктор этого объекта. MyValue же QObject - ему не надо даже метаобъектную систему задействовать, деструктор же виртуальный.
Есть еще например такое https://doc.qt.io/qt-5/qqmlengine.html#setObjectOwnership
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #6 : Ноябрь 27, 2020, 14:16 »

Когда вы упомянули про деструктор, я понял, что туплю  Грустный. Добавил деструктор, туда qDebug. Теперь стало понятно, как все работает. Во-первых, эти объекты (которые new) удаляются, как минимум, при удалении самого движка. Во-вторых, если ничего не предпринимать, то движок сам решает, когда ему освобождать память (я об этом читал), но можно это сделать принудительно: после выполнения скрипта вызвать myEngine->collectGarbage(). Объекты исправно удаляются. Теперь я спокоен Улыбающийся
Спасибо, тема закрыта.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.286 секунд. Запросов: 22.