Проблемы во время выполнения при смешивании библиотек из разных версий Visual Studio - PullRequest
4 голосов
/ 22 декабря 2009

Я столкнулся с неожиданной ошибкой доступа при запуске проекта, который я создал с использованием двух разных версий Visual Studio. Моя общая конфигурация следующая:

  • LibA - статическая библиотека, статическая связь во время выполнения, msvc 8.0
  • LibB - статическая библиотека, статическая связь во время выполнения, msvc 9.0
  • Мой целевой проект для интеграции - это MSVC 9.0 COM dll, который статически связывает вышеуказанные библиотеки

Этот проект создается, но падает во время выполнения с нарушением прав доступа в некотором коде STL. Похоже, стек указывает, что я прошел через заголовки обеих версий (8 и 9) во время вызова оператора вставки потока. Я понимаю, что это проблема.

Каким-то образом этот звонок:

ost << std::dec << port_; //(originating from an object in LibA)

... проходит через следующую трассировку стека:

std::basic_ostream::operator<<(...) (ostream:283, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::put(...) (xlocnum:888, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::do_put(...) (xlocnum:1158, msvc 9.0 version!! !@#$!%! <-- not expected, since LibA was built with msvc 8.0)
std::ios_base::flags() (xiosbase:374, msvc 9.0 version <-- follows from above)

Нарушение доступа происходит в std :: ios_base :: flags (). Я подозреваю, что это связано со смешением реализаций в стеке вызовов (хотя я не уверен).

Мои вопросы.

1.) Вероятная причина этого нарушения доступа - смешивание реализаций заголовка msvc?
2.) Есть ли способ предотвратить смешивание этих реализаций?
3.) Есть ли лучший способ настроить эти три проекта для интеграции (при условии, что перемещение LibA из msvc 8.0 нежелательно)?

Мне известны идеи, поднятые в этом вопросе и этом . Здесь меня больше всего интересует эта конкретная проблема, и есть ли способ ее избежать.

Любые идеи будут оценены.

Ответы [ 2 ]

7 голосов
/ 22 декабря 2009

Вы не можете использовать разные реализации STL в одном проекте. Это означает, что даже разные версии одного и того же компилятора. Если в вашем LibA есть функция, которая принимает std :: vector в качестве аргумента, вам разрешено передавать только векторный объект из STL, с которым был создан LibA. Вот почему многие библиотеки C ++ предоставляют только C API.

Либо вы меняете свой API, либо перестраиваете все свои проекты, используя один и тот же компилятор.

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

1 голос
/ 22 декабря 2009

Нет гарантии двоичной совместимости библиотеки между основными версиями MSVC. Код STL - это в основном шаблонный код, который расширяется в ваш код. Так что у вас статические библиотеки, вероятно, есть несовместимые куски кода STL внутри них.

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

Лучшее решение - собрать все с одной и той же версией компилятора. Если вы не можете этого сделать (например, если одна из библиотек сторонних производителей), вы, вероятно, застряли.

...