Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Конфликт реализаций std::vector или что-то странное

1.8K
30 марта 2011 года
Arkady
153 / / 18.12.2007
Здравствуйте,

Очень удобно для обмена данными между функциями использовать STL контейнеры.
Однако так вышло, что визуалка, нарисованная на Qt, при передаче такого контейнера в библиотеку (написанную на CBuilder), получает exception при вызове метода push_back внутри библиотеки (аналогичный код на клиенте, написанном на CBuilder работает корректно).

Интерфейс:
 
Код:
long __stdcall GetListOfQ(void* pstk, void* DataSource, long DSSize, std::vector<I_archQuery*>& Q);


Код клиента:
 
Код:
std::vector<I_archQuery*> Q;
long res = GetListOfQ(pstk, (void*)DataSource, 4, Q);


Код библиотеки
 
Код:
long __stdcall C_Source::GetListOfQ(void* pstk, void* DataSource, long DSSize, std::vector<I_archQuery*>& Q)
{
    Q.clear();
    for (unsigned i = 0; i < m_QList.size(); ++i)
    {
        Q.push_back((I_archQuery*)&m_QList); //!!!!
    }
}

Exception вылетает на строчке, помеченной //!!!!.
Насколько я понял, проблема заключается в том, что имеются разные реализации STL. Так ли это?
При попытке скачать какой-то "эталон" с stlport и вшить его в Qt, получил целую кучу проблем совместимости, т.к. winbase.h, идущий вместе с stlport пересекается с windows.h из Qt по некоторым именам некорректно и т.п..

Как правильно решить эту задачу? Вообще насколько корректно передавать данные через STL контейнеры? Мне казалось, что раз STL - это Standart ..., то проблем быть не должно.
Может быть проблема не в STL, а в том, что Builder как-то не так формирует dll?
QT подгружал dll динамически.

Важно!! При этом метод, который возвращает std::string - выполняется корректно.

Спасибо заранее за помощь!
11
30 марта 2011 года
oxotnik333
2.9K / / 03.08.2007
А потому что реализация STL у каждого компилятора разная. Тут выход один - передавать простыми массивами, либо через SAFEARRAY
1.8K
30 марта 2011 года
Arkady
153 / / 18.12.2007
Цитата: oxotnik333
А потому что реализация STL у каждого компилятора разная. Тут выход один - передавать простыми массивами, либо через SAFEARRAY


Честно говоря, первое, что мне пришло в голову, это сделать так:

Код:
template<typename T>
class C_VirtualVector : public std::vector<T>
{
    virtual void __stdcall vpush_back(T& newT)
    {
          push_back(newT);
    }
    virtual unsigned __stdcall vsize()
    {
          return size();
    }
};

Далее создавать этот класс и передавать его. Тогда, несмотря на разные реализации непосредственно STL, если дергать виртуальные методы внутри библиотеки, которые попадут в таблицу виртуальных функций на одни и те же места вне зависимости от реализации STL, то все должно быть хорошо.
Чем плохо такое решение?
11
30 марта 2011 года
oxotnik333
2.9K / / 03.08.2007
Я бы очканул так делать. В конечном итоге, push_back залезет в память не своего процесса и хз чего там натворит.
1.8K
30 марта 2011 года
Arkady
153 / / 18.12.2007
Цитата: oxotnik333
Я бы очканул так делать. В конечном итоге, push_back залезет в память не своего процесса и хз чего там натворит.


Ну, между процессами вряд ли, там все в одном процессе. По-моему, единственная проблема как раз в том, чтобы дернуть нужный метод, а таблица виртуальных функций как раз подходит....
Возможно я не понимаю опасности, но тогда я ее все еще не понимаю)

260
31 марта 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: Arkady
Честно говоря, первое, что мне пришло в голову, это сделать так:
Код:
template<typename T>
class C_VirtualVector : public std::vector<T>
{
    virtual void __stdcall vpush_back(T& newT)
    {
          push_back(newT);
    }
    virtual unsigned __stdcall vsize()
    {
          return size();
    }
};

Далее создавать этот класс и передавать его. Тогда, несмотря на разные реализации непосредственно STL, если дергать виртуальные методы внутри библиотеки, которые попадут в таблицу виртуальных функций на одни и те же места вне зависимости от реализации STL, то все должно быть хорошо.
Чем плохо такое решение?



А каким образом, реализовав подобный шаблон вы уходите от проблемы?

PS: Чисто для интереса, какой компилятор используется с Qt?

1.8K
31 марта 2011 года
Arkady
153 / / 18.12.2007
Цитата: Ramon
А каким образом, реализовав подобный шаблон вы уходите от проблемы?



Я думал, что проблема в том, что адрес метода в разных реализациях меняется, поэтому dll, думая, что дергает один метод, реально дергает другой, отсюда и падение.
А такое исправление должно было дать таблицу виртуальных функций, а значит строго закрепить адрес нужной функции для всех, кто пользуется этим шаблоном.

Где ошибка в рассуждениях?

Но так не получилось. Я полагаю потому, что реализация работы с шаблонами у этих компиляторов может быть разной, а потому в принципе не стоит использовать шаблоны в качестве интерфейса.
В итоге мне пришлось создать целую кучу интерфейсов, никак не связанных с STL, для доступа к данным :)

Цитата: Ramon
PS: Чисто для интереса, какой компилятор используется с Qt?



minGW.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог