LINUX.ORG.RU

[Qt][S60] некорректная работа кода без dynamic_cast


0

1

Есть кусок кода, взятый отсюда:

bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
{
    if (d->buffer != 0 && d->data == 0) {
        Q_ASSERT(d->bytesPerLine == 0);
        Q_ASSERT(d->mappedBytes == 0);

        // Вот здесь программа, запущенная на телефоне, перестает отвечать
        d->data = d->buffer->map(mode, &d->mappedBytes, &d->bytesPerLine);

        return d->data != 0;
    }

    return false;
}
И он же, но слегка подправленный.
bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
{
    if (d->buffer != 0 && d->data == 0) {
        Q_ASSERT(d->bytesPerLine == 0);
        Q_ASSERT(d->mappedBytes == 0);

        // Отладка показала, что в d->buffer хранится именно QImageVideoBuffer
        QImageVideoBuffer *ivb = dynamic_cast<QImageVideoBuffer*>(d->buffer);
        if (ivb) {
            // а тут уже вызов проходит гладко
            d->data = ivb->map(mode, &d->mappedBytes, &d->bytesPerLine);
        }

        qDebug() << d->buffer << &(*d->buffer); // 0x62aab0 0x62aab0
        qDebug() << typeid(*d->buffer).name();  // приложение зависает

        return d->data != 0;
    }

    return false;
}

Адрес в d->buffer не меняется, то есть тот же, что и здесь:

QVideoFrame::QVideoFrame(const QImage &image)
    : d(new QVideoFramePrivate(
            image.size(), pixelFormatFromImageFormat(image.format())))
{
    if (d->pixelFormat != Format_Invalid) {
        d->buffer = new QImageVideoBuffer(image);
        qDebug() << d->buffer << typeid(*d->buffer).name(); // 0x62aab0 17QImageVideoBuffer
    }
}

Кто может объяснить мне такое поведение?

★★

Ответ на: комментарий от namezys

Эм, что там разбивать? При попытке вызвать map подвисает, причем сам map не исполняется, словно d->buffer указывает на какой-нибудь левый участок памяти.

rival ★★ ()
Ответ на: комментарий от namezys

Хм, вот такой трюк тоже позволяет избежать ошибки:

QAbstractVideoBuffer *buffer = d->buffer;
d->data = buffer->map(mode, &d->mappedBytes, &d->bytesPerLine);

rival ★★ ()
Ответ на: комментарий от runtime

Пересборка всего с нуля решила проблемы, в том числе и обнаружившиеся косяки в другом месте, где их уж точно не следовало ожидать.

Но интересно, зачем тебе нужно было знать их адреса? Какая была у тебя мысль?

rival ★★ ()
Ответ на: комментарий от rival

Если я правильно понимаю, то это кусок из QtMultimedia, а значит configure вызывает тот же qmake. И вы сами же этот код правили. Если так, то пересборка с помощью повторного вызова make может спокойно создать битый бинарник. Такая вот особенность qmake.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Эм, я думал, что имелся ввиду прямой вызов qmake, а так да, через qmake. А за информацию про особенность спасибо, учту в будущем.

rival ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.