Конфликт реализаций std::vector или что-то странное
Очень удобно для обмена данными между функциями использовать STL контейнеры.
Однако так вышло, что визуалка, нарисованная на Qt, при передаче такого контейнера в библиотеку (написанную на CBuilder), получает exception при вызове метода push_back внутри библиотеки (аналогичный код на клиенте, написанном на CBuilder работает корректно).
Интерфейс:
Код клиента:
long res = GetListOfQ(pstk, (void*)DataSource, 4, 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 - выполняется корректно.
Спасибо заранее за помощь!
Честно говоря, первое, что мне пришло в голову, это сделать так:
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, то все должно быть хорошо.
Чем плохо такое решение?
Ну, между процессами вряд ли, там все в одном процессе. По-моему, единственная проблема как раз в том, чтобы дернуть нужный метод, а таблица виртуальных функций как раз подходит....
Возможно я не понимаю опасности, но тогда я ее все еще не понимаю)
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?
Я думал, что проблема в том, что адрес метода в разных реализациях меняется, поэтому dll, думая, что дергает один метод, реально дергает другой, отсюда и падение.
А такое исправление должно было дать таблицу виртуальных функций, а значит строго закрепить адрес нужной функции для всех, кто пользуется этим шаблоном.
Где ошибка в рассуждениях?
Но так не получилось. Я полагаю потому, что реализация работы с шаблонами у этих компиляторов может быть разной, а потому в принципе не стоит использовать шаблоны в качестве интерфейса.
В итоге мне пришлось создать целую кучу интерфейсов, никак не связанных с STL, для доступа к данным :)
minGW.