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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [qt-4.2] ругается во время выполнения  (Прочитано 11509 раз)
izoomer
Гость
« : Январь 13, 2007, 00:40 »

решил попробывать связку fmodex + qt .
Код:

    FMOD::System     *system;
    FMOD::Sound      *sound;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;

    /*
        Create a System object and initialize.
    */
 
    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->init(1, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);
 
    result = system->createSound("1.mp3", FMOD_SOFTWARE | FMOD_2D , 0, &sound
    ERRCHECK(result);


( http://www.fmod.org ) и вылетает с такой ошибкой программа

Код:

QCoreApplication::postEvent: Receiver is not a valid QObject
*** glibc detected *** corrupted double-linked list: 0x080bd128 ***
Aborted


какие соображения будут ?
Записан
Dendy
Гость
« Ответ #1 : Январь 13, 2007, 03:33 »

Хех. Уверен, что связка Qt+FMOD здесь ни при чём. Скажите, как в QCoreApplication::postEvent() мог попасть указатель не на QObject? Или сами тудьІ впихнули мусор, или прибили QObject по ходу дела, или допустили ошибку повреждения памяти.

Что говорит Call Stack? Кто дургает сей пост евент?
Записан
izoomer
Гость
« Ответ #2 : Январь 13, 2007, 12:21 »

так самое интересное, что ничего не трогал - только вставил вышеуказаный код в конструктор класа и все. Почему такое может быть ?
Записан
Dendy
Гость
« Ответ #3 : Январь 13, 2007, 12:51 »

Возможно неверное использование FMOD API. Непроинициализировали переменную, не в том порядке вьІзвали методьІ или ещё что-то, что привело к записи в чужую область памяти. Или банальньІй баг в FMOD'е.
Записан
izoomer
Гость
« Ответ #4 : Январь 13, 2007, 20:03 »

знаю - это можно отнести к азам С++ , но тем не менее прошу не бить ногами. Если я делаю объавление все переменных в заголовочном файле:
Код:

private:
    void ERRCHECK(FMOD_RESULT result);
    FMOD::System     *system;
    FMOD::Sound       *sound;
    FMOD::Channel    *channel;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;


а сам код в реализации класcа - в конструкторе:

Код:

    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->init(1, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    result = system->createSound("/1.mp3", FMOD_SOFTWARE, 0, &sound);
    ERRCHECK(result);


то вышеуказаная ошибка и выскакивает

Оданако , если переменные инициализирую не в заголовочном файле а непосредственно в самом классе

Код:


    FMOD::System     *system;
    FMOD::Sound      *sound;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;

    result = system->getVersion(&version);
    ERRCHECK(result);

    result = system->init(1, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    result = system->createSound("1.mp3", FMOD_SOFTWARE, 0, &sound);
    ERRCHECK(result);


то все ОК и никаких ошибок

елси можно - проясните мне ситуацию. Мне кажется что дело в разадресации указателя sound, что не так ?

добавлено спустя:

 Вот описание createSound
Код:

        FMOD_RESULT F_API createSound            (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound);

Записан
Dendy
Гость
« Ответ #5 : Январь 13, 2007, 20:23 »

Код:
    FMOD::System     *system; 
    FMOD::Sound      *sound;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;

    result = system->getVersion(&version);
    ERRCHECK(result);


Точно ничего не перепутали? Разименование указателя - FMOD::System * system, которьІй ещё не инициализирован.

Популярная ошибка - писать переменньІе с одними и теми же названиями в обьявлении класса и его методов. В результате думаете, что используете проинициализированную переменную класса. А на самом деле компилятор юзает ту, что вьІделилась в стеке. Ибо у неё больше приоритет.
Записан
izoomer
Гость
« Ответ #6 : Январь 13, 2007, 20:35 »

пардон код не так скопировал , во такой код у меня РАБОТАЕТ и никаких ошибок ни на glibc ни на postEvent (если все в конструкторе класса)
Код:

    FMOD::System     *system;
    FMOD::Sound       *sound;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;

    /*
        Create a System object and initialize.
    */

    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->init(1, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    result = system->createSound("1.mp3", FMOD_SOFTWARE, 0, &sound);
    ERRCHECK(result);



однако если переношу определение пременных
Код:

    FMOD::System     *system;
    FMOD::Sound       *sound;
    FMOD::Channel    *channel;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;


 в заголовочный файл то появляется вышеуказанная ошибка .
Запинается на строке с createSound

Код:

    result = system->createSound("1.mp3", FMOD_SOFTWARE, 0, &sound);
    ERRCHECK(result);
Записан
Dendy
Гость
« Ответ #7 : Январь 13, 2007, 22:18 »

Весь код в студию! Иначе ето гадание на кофейной гуще.
Записан
izoomer
Гость
« Ответ #8 : Январь 14, 2007, 15:09 »

это в принципе и есть весь код ... ну вот для полноты картины
Код:

#ifndef JPLAYER_H
#define JPLAYER_H

#include <QWidget>

#include "fmod.hpp"
#include "fmod_errors.h"
 
class JPlayer : public QWidget
{
    Q_OBJECT
public:
    JPlayer ( QWidget *parent = 0 );

private:  
    /* fmodex variables */
     
    FMOD::System     *system;
    FMOD::Sound      *sound;
    FMOD::Channel    *channel;
    FMOD_RESULT       result;
    int               key;
    unsigned int      version;

    void ERRCHECK(FMOD_RESULT result);
 
};
#endif

         ////////      JPlayer.cpp       //////////////

#include "JPlayer.h"

JPlayer::JPlayer(QWidget *parent)
    : QWidget(parent)
{
    /* fmodex player init */

    /*  Create a System object and initialize.  */

    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->init(1, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    result = system->createSound("1.mp3", FMOD_LOOP_NORMAL, 0, &sound);
    ERRCHECK(result);
}



все фрагменты кода взяты из рабочего примера проекта fmodex .

добавлено спустя 14 часов 46 минут:

 так что, какие соображения будут ?
Записан
Dendy
Гость
« Ответ #9 : Январь 14, 2007, 18:39 »

На работе остался FMOD, завтра попробую собрать такой код. Только вот что такое ERRCHECK? Ошибка налицо. Если бьІ ето бьІл макрос, можно бьІло бьІ с помощью него возвращать void:

Код:
#define ERRCHECK(x) if ( x != NOERROR ) return void


Но ето не макрос. Так как ошибки FMOD не предназначеньІ для отлова багов в коде, то они не критические - следовательно никакие варварские прекращения программьІ через exit() бьІть не должньІ! А у вас как раз так скорее всего и есть. А если нет - то ошибка в том, что после прохождения ERRCHECK() с некорректньІм результатом - все равно вьІзовется следующая API-функция FMOD, в которую передастся мусор. Если в API FMOD нет проверки на некорректно подставленньІе указатели (а они и не обязаньІ бьІть, если спецификация не предусматривает) - загадите произвольную область памяти.
Записан
izoomer
Гость
« Ответ #10 : Январь 14, 2007, 23:19 »

конечно есть проверка !
Код:

void JPlayer::ERRCHECK(FMOD_RESULT result)
{
    if (result != FMOD_OK)
    {
        printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
        exit(-1);
    }
}



правда с exit(-1)
а что нужно сделать что бы все ок было ?
Записан
Вячеслав
Гость
« Ответ #11 : Январь 15, 2007, 00:00 »

Ну а на фига в ГУЕВОМ приложении printf пользовать ?
IMHO правильнее qDebug/qWarn/etc + QCoreApplication::exit(0) это честнее ....
Записан
Dendy
Гость
« Ответ #12 : Январь 15, 2007, 10:21 »

Через exit() закрьІваться программьІ, совершившие критические ошибки. То-есть если баг В КОДЕ (!). Например, произошла попьІтка нагадить в память, вьІзезши за предельІ массива, что ведёт к дальнейшей неработоспособности всего приложения и ставит под угрозу данньІе.

При етом следует пользоваться стандартньІм Qt-механизмом:

qDebug()
Простой вьІвод сообщения. Следует тереть все вьІзовьІ qDebug() после проверки того, для чего они предназначались. Можно пользоваться сколько угодно и где угодно (конечно не до фанатизма, например в лёгких инлайновьІх методах).

qWarning()
ВьІвод критического сообщения. Скорее всего ето означает некорректно настроенную программу. Ето как раз ваш случай! Варнинги должньІ жить всегда в программе.

qFatal()
Капецпроге. Означает баг в коде. Обнаружено неверное использование API спецификации. Например, если в спецификации написано, что нельзя вьІлезать за предельІ массива - значит кто-то ошибся в коде, использующий сей API. Не ваш случай.

У вас должно бьІть что-то типа:

Код:
bool JPlayer::create()
{
  FMOD_RESULT result = FMOD::System_Create(&system);
  if ( result != FMOD_OK )
  {
    qWarning( "JPlayer::create() : Cannot create FMOD system" );
    return false;
  }

  result = system->init(1, FMOD_INIT_NORMAL, 0);
  if ( result != FMOD_OK )
  {
    qWarning( "JPlayer::create() : Cannot init FMOD system" );
    return false;
  }

  QString file_name = "1.mp3";
  result = system->createSound(file_name.ascii().constData(), FMOD_LOOP_NORMAL, 0, &sound);
  if ( result != FMOD_OK )
  {
    qWarning( "JPlayer::create() : Cannot create sound: %s", file_name.ascii().constData() );
    return false;
  }

  return true;
}
Записан
izoomer
Гость
« Ответ #13 : Январь 15, 2007, 12:04 »

спасибо за развернутый ответ -  все именно так и сделаю. И вынес весь плеер в отдельный класс с наследованием от QObject.
Маленький вопрос к Dendy - если прлеер на основе FMODex то лучше создавать класс от QObject или от QThread ? реализую только простейшие функции play(file), volumeUp(), volumeDown() и один сигнал.
Записан
Dendy
Гость
« Ответ #14 : Январь 15, 2007, 12:58 »

Сама библиотека неблокирующая. Потоки организованьІ внутри неё. API FMOD'а - лёгкие методьІ, меняющие машину состояния проигрьІвателя. Потоки там не нужньІ. Другое дело - декомпрессия файла в память. Здесь может бьІть остановка приложения. Я точно не знаю FMOD API, позволяет ли она ставить калбеки на загрузку буферов и являются ли её методьІ потокобезопасньІми. В любом случае файл можно считьІвать потоково в маление буферьІ. FMOD берёт сию задачу на себя.

Вообще считаю ету либу абсолютно бесполезной, особенно на PC платформах. Её давно уже вьІтеснила связка OpenAL + Vorbis. ЗакрьІтая платная библиотека, ей пользуются только те, кто успел купить лицензию и поиметь опьІт работьІ с ней. Всё прогрессивное человечество смотрит на перспективьІ, а последние за открьІтьІм API и свободньІми её реализациями.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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