Nano Hash - криптовалюты, майнинг, программирование

Сбой QObject::connect при signalOffset(senderMetaObject) из-за того, что QMetaObject::superdata содержит нулевые данные

Мой код подключения выглядит следующим образом:

QObject::connect(_scene, &VScene::activeObjectChanged, _scene->manipulatorNode(), &VManipulatorNode::onActiveObjectChanged);

VScene является подклассом VNode, который является подклассом QObject. Оба они содержат макрос Q_OBJECT.

VScene является отправителем сигнала:

class VScene : public VNode
{
    Q_OBJECT
    public slots:
    void        markActiveObject(VObject *obj);
    void        unmarkActiveObject(VObject *obj);
signals:
    void        activeObjectChanged(VObject *obj);
}

ВУзел:

class VNode : public QObject
{
    Q_OBJECT
}

Вманипулятор:

class VManipulatorNode : public VNode
{
public:
    void onActiveObjectChanged(VObject *obj);
}

Программа вылетает при вызове QObject::connect, в функции

    signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);

Во время отладки я обнаружил, что superdatapointer QMetaObject отправителя VScene содержит только нулевые данные.

Я вижу, что QMetaObject из VScene будет указывать на QMetaObject из VNode, а затем QMetaObject из VNode будет указывать на QMetaObject из QObject. Здесь, в месте аварии, QMetaObject из VScene содержит только нулевые данные.

Все файлы moc, включая moc_VScene и moc_VNode, обычно генерируются Qt.

moc_VScene.cpp:

const QMetaObject vk::VScene::staticMetaObject = {
{ &VNode::staticMetaObject, qt_meta_stringdata_vk__VScene.data,
  qt_meta_data_vk__VScene,  qt_static_metacall, Q_NULLPTR, Q_NULLPTR}
};

moc_VNode.cpp:

struct qt_meta_stringdata_vk__VNode_t {
QByteArrayData data[1];
char stringdata0[10];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    qptrdiff(offsetof(qt_meta_stringdata_vk__VNode_t, stringdata0) + ofs \
    - idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_vk__VNode_t qt_meta_stringdata_vk__VNode = {
    {
        QT_MOC_LITERAL(0, 0, 9) // "vk::VNode"
    },
    "vk::VNode"
};
#undef QT_MOC_LITERAL

static const uint qt_meta_data_vk__VNode[] = {

 // content:
   7,       // revision
   0,       // classname
   0,    0, // classinfo
   0,    0, // methods
   0,    0, // properties
   0,    0, // enums/sets
   0,    0, // constructors
   0,       // flags
   0,       // signalCount

   0        // eod
};

void vk::VNode::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int     _id, void **_a)
{
    Q_UNUSED(_o);
    Q_UNUSED(_id);
    Q_UNUSED(_c);
    Q_UNUSED(_a);
}

const QMetaObject vk::VNode::staticMetaObject = {
    { &QObject::staticMetaObject, qt_meta_stringdata_vk__VNode.data,
  qt_meta_data_vk__VNode,  qt_static_metacall, Q_NULLPTR, Q_NULLPTR}
};

ПРИМЕЧАНИЕ: при отладке в Visual Studio показано, что VNode::staticMetaObject содержит только нулевые данные, но это так странно, что все его статические члены, включая qt_meta_stringdata_vk__VNode и qt_meta_data_vk__VNode, выглядят правильно (не нулевыми). Вот доказательства введите здесь описание изображения

Код, излучающий сигнал:

void VScene::markActiveObject(VObject *obj)
{
    if (obj){
        obj->markActive();
        emit activeObjectChanged(obj);
    }
}
25.04.2016

  • Я просто основываю это на том, что я читал об официальных примерах Qt (никогда не кодируя в нем). Разве вы не хотите вызывать connect с вашими аргументами, обернутыми макросами SIGNAL и SLOT? и вы не отметили свой слот с помощью макроса slot. и это Qt, вероятно, где-то еще нужны больше загадочных макросов. 25.04.2016
  • @underscore_d, так как Qt5 лучше подключать через указатели методов, а не макросы SIGNAL/SLOT 25.04.2016
  • @AndreiR Спасибо, я рад, что они модернизируют некоторые части API. Тогда им действительно следует обновить свои руководства/примеры... которые утверждают, что предназначены для QT 5.6, но по-прежнему везде используют старый синтаксис connect (почти?). 25.04.2016
  • АндрейР прав, это улучшение по сравнению с Qt5. woboq.com/blog/new-signals-slots-syntax- in-qt5.html 25.04.2016
  • Вы пробовали это без передачи параметра VObject * ... т.е. удалить параметр из фикций слота/сигнала, просто чтобы посмотреть, работает ли он. Причина, по которой я предлагаю это, заключается в том, что обычно вы должны регистрировать свои пользовательские типы с помощью qRegisterMetaObject (я думаю, это называется так)... однако я не уверен, разрешает ли наследование QObject это или нет... 25.04.2016
  • @khanhhh89 Спасибо за ссылку! Это несколько массовых улучшений подключения сигнала (по сравнению с низким базовым уровнем). Но мне приходится смеяться: какая из них красивее, это дело вкуса. На самом деле это не так: правильный синтаксис C++ и проверка во время компиляции объективно лучше, чем взлом макросов и строк во время выполнения. Поэтому я рад видеть, что они начинают двигаться в этом направлении. В любом случае, извините, я больше не буду болтать по вашему вопросу :-) 25.04.2016
  • Можете ли вы опубликовать свой код для VScene::manipulatorNode() и для того, где вы emit activeObjectChanged() 25.04.2016
  • @code_fodder: я обновил вопрос, добавил запрошенный вами код и предоставил дополнительную информацию о нулевых статических данных moc. 25.04.2016
  • @ khanhhh89 Но я не вижу в вашем заголовке VScene вашу функцию-член manipulatorNode() Вы опубликовали реализацию, но она не отображается в вашем заголовке - она ​​отсутствует или вы просто не опубликовали ее? Я имею в виду, что _scene относится к типу VScene, а вы называете что-то под названием _scene->manipulatorNode(), где это? 25.04.2016
  • @code_fodder: я просто упрощаю код. Все указатели _scene и _scene-›manipulatorNode действительны. 25.04.2016

Ответы:


1

Первое, что я замечаю, это то, что вы должны изменить:

public:
    void onActiveObjectChanged(VObject *obj);

to:

public slots:
    void onActiveObjectChanged(VObject *obj);

Из предоставленной информации не уверен, что это решит проблему, но это неправильно.

25.04.2016
  • Я пробовал, но все равно вылетает. Но документ QT допускает, что функция слота является любой функцией 25.04.2016
  • На самом деле вы правы, вы можете использовать любую функцию... единственная реальная разница в том, что когда вы используете макрос SLOT (или просматриваете список участников в автозаполнении), эта функция отображается как слот. 25.04.2016

  • 2

    Я столкнулся с той же проблемой. Если это та же причина, я полагаю, что это связано с QTBUG-38876. В моем случае соединения сигнал/слот создавались в конструкторе статического объекта. Задержка соединения после инициализации глобальной статики решила проблему для меня.

    05.08.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..