Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа функции, Полтргейст 
:(
    Опции темы
Acer
Дата 4.12.2008, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



Есть метод класса. Его работа заключается в выборке данных из базы и записи этих данных в определенное поле класса.
Вот код, который работает:
Код

void RModuleCore::updateData(){
    long n = 0;
    std::string q( "SELECT atm FROM atm_data WHERE id = '" );
    q += this->mid; q += "'";
    n = this->rdbc.execQuery( q );
    if ( n > 0 ){
        this->data_atm.resize( n );
        char atm[10];
        long ds = 0;
        this->rdbc.getCellValue( 1, atm, 10, &ds, 1 );
        this->data_atm[0].atm = atm;
    }
}

А вот код, который не работает:
Код

void RModuleCore::updateData(){
    long n = 0;
    std::string q( "SELECT atm FROM atm_data WHERE id = '" );
    q += this->mid; q += "'";
    n = this->rdbc.execQuery( q );
    if ( n > 0 ){
        this->data_atm.resize( n );
        char atm[10];
        long ds = 0;
        this->rdbc.getCellValue( 1, atm, 10, &ds, 1 );
        this->data_atm[0].atm = atm;
    } else {
        this->clearData();
    }
}

Подскажите, в чем проблема? Почему при добавлении 2-х строк кода в выше приведенную функцию вот эта
Код

this->rdbc.execQuery( q );

возвращает -1 ?


--------------------------------------------------------------
Код

void RModuleCore::clearData(){
    this->data_atm.clear();
    this->data_global.clear();
}

PM MAIL   Вверх
J0ker
Дата 4.12.2008, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



такое может быть только в одном случае - если во втором случае перед этим вызывался любой код, который изменил состояние rdbc
приведенный вами код никакой информации не несет - из него лишь можно сделать предположение, что перед вызовом RModuleCore::updateData() был еще один вызов RModuleCore::updateData(), который в else изменил состояние rdbc, и последующий вызов привел к ошибке.


--------------------
user posted image
PM MAIL   Вверх
Acer
Дата 4.12.2008, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



хм... вроде нигде не должно меняться состояние обьекта rdbc...
Ну вот, смотрите:
начну с main:
Код

    RModule *md;
    for ( int i = 0; i < ( int )modules.size(); i++ ){
        screen->showMessage( modules[i].key.c_str(), Qt::AlignRight | Qt::AlignCenter );
        md = new RModule( &gcfg, mw.instance(), ws );
        md->init( modules[i].key.c_str(), modules[i].value.c_str() );
        ws->addModule( md );
    }

тут из конфиг файла беру данные о модулях и создаю обьекты для каждого модуля. Затем они добавляются в ws (workspace)
Далее после инициализации модулей они живут сами по себе. А именно:
в конструкторе класса RModule:
Код

this->connect( timer, SIGNAL( timeout() ), this, SLOT( updateData() ) );

Это Qt. По истечению времени таймера запускается метод класса RModule - updateData()
RModule::updateData()
Код

void RModule::updateData(){
    if ( this->mod_core->isConnected() ){
        this->mod_core->start();
    }
}

RModuleCore::isConnected()
Код

bool RModuleCore::isConnected(){
    return this->rdbc.isConnected();
}

RODBC::isConnected()
Код

bool RODBC::isConnected(){
    char value[256];
    long value_s;
    return SQLGetConnectAttr( this->hdbc, SQL_ATTR_CONNECTION_DEAD, value, 256, &value_s ) == SQL_SUCCESS;
}

mod_core - это свойство обьекта класса RModule и является экземпляром класса RModuleCore.
RModuleCore для каждого модуля запускается в отдельном потоке. При выполнении mod_core->start(); запускается метод run:
RModuleCore::run()
Код

void RModuleCore::run(){
    this->updateData();
    emit this->endWorking();
}

После завершения работы метода this->updateData() в классе RModuleCore генерируется сигнал, который оповещает RModule о том, что нужно запустить updateDisplay();
RModuleCore::updateData()
Код

void RModuleCore::updateData(){
    long n = 0;
    std::string q( "SELECT atm FROM atm_data WHERE id = '" );
    q += this->mid; q += "'";
    n = this->rdbc.execQuery( q );
    if ( n > 0 ){
        this->data_atm.resize( n );
        char atm[10];
        long ds = 0;
        this->rdbc.getCellValue( 1, atm, 10, &ds, 1 );
        this->data_atm[0].atm = atm;
    } else {
        this->clearData();
    }
}


RModule::updateDisplay()
Код

void RModule::updateDisplay(){
    if ( this->mod_core->getDataAtm().size() == 0 ){
        this->setIconStat( this->ind_conn_db, false );
        return;
    } else {
        this->setIconStat( this->ind_conn_db, true );
    }

    QTreeWidgetItem *item = new QTreeWidgetItem;
    item->setText( 0, this->mod_core->getDataAtm().at( 0 ).atm.c_str() );
    this->atm_list->addTopLevelItem( item );

    this->windowActivate();
    this->windowFlash();
    this->playSound();
}

В методе RModule::updateDisplay() берутся данные, которые RModuleCore достал из базы:
RModuleCore::getDataAtm()
Код

std::vector<_data_atm> RModuleCore::getDataAtm(){
    return this->data_atm;
}

Данные представляют собой вектор структур(мало полей, так как программа в стадии разработки):
Код

typedef struct {
    std::string atm;
} _data_atm;

Далее, что касается класса, работающего с базой:

RODBC::execQuery
Код

long RODBC::execQuery(std::string q){
    int n = ( int )q.size();
    if ( this->exec( q, n + 1 ) ){
        this->connection = true;
        return this->getRowsCount();
    } else {
        return -1;
    }
}


RODBC::exec
Код

bool RODBC::exec(std::string q,int q_length){
    return SQLExecDirect( this->hstmt, ( UCHAR* )q.c_str(), q_length ) == SQL_SUCCESS;
}


RODBC::getRowsCount
Код

long RODBC::getRowsCount(){
    long n;
    SQLRowCount( this->hstmt, &n );
    return n;
}


RODBC::getCellValue
Код

bool RODBC::getCellValue(int idx,void *value,long v_size,long *d_size,short cm){
    RETCODE rc;
    if ( cm == 1 ){
        SQLFetch( this->hstmt );
    }
    return SQLGetData( this->hstmt, idx, SQL_C_DEFAULT, value, v_size, d_size ) == SQL_SUCCESS;
}


Это сообщение отредактировал(а) Acer - 4.12.2008, 23:12
PM MAIL   Вверх
J0ker
Дата 4.12.2008, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



ээээ
давайте вы просто дебагером пройдетесь и посмотрите все обращения к rdbc, а заодно и сверитесь с документацией по библиотеке, предоставляющий этот объект



--------------------
user posted image
PM MAIL   Вверх
Acer
Дата 4.12.2008, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



Я сам писал эту библиотеку smile
PM MAIL   Вверх
J0ker
Дата 4.12.2008, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



тем более


--------------------
user posted image
PM MAIL   Вверх
Acer
Дата 4.12.2008, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



Еще один интересный факт:
Первый запрос проходит нормально, а второй уже возвращает -1
PM MAIL   Вверх
J0ker
Дата 5.12.2008, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



это я и имел ввиду
у вас объект вероятно не детерминирован

Это сообщение отредактировал(а) J0ker - 5.12.2008, 00:35


--------------------
user posted image
PM MAIL   Вверх
Acer
Дата 5.12.2008, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



Вобщем, проблема в том, что я еще не совсем понимаю многопоточную обработку данных....
Я заменил библиотеку для работы с базами. Но непонятно вот-что: при старте программы все модули коннектятся к базе. Но потом соединение остается только у последнего. Все, кто грузился ранее, теряют связь с базой :(
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0526 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.