Вызов функции переходит на неправильную функцию - PullRequest
13 голосов
/ 15 декабря 2008

Я собираю статическую библиотеку c ++ в vs2008, и в этом решении у меня также есть стартовый проект, который использует lib, и это прекрасно работает.

Но при использовании библиотеки lib в другом решении я получаю ошибку проверки во время выполнения. «Значение ESP не было правильно сохранено в вызове функции» Проходя по коду, я заметил, что функция foo () переходит на bar () вместо этого прямо перед сбоем. Рассматриваемые функции являются просто обычными функциями и не имеют указателей на функции.

Кто-нибудь знает, что может происходить и почему это работает при использовании библиотек из того же решения?

edit: функции (методы) являются частью класса, если это помогает.

Ответы [ 5 ]

15 голосов
/ 16 декабря 2008

Простите за то, что я констатировал очевидное кровотечение, но ... Я видел, как подобные вещи происходили много раз раньше, когда файлы объектов (.o) и заголовков (.h) не синхронизированы. Особенно в отношении виртуальных методов.

Учтите: объектный файл скомпилирован с заголовком:

class Foo { virtual void f(); };

Но тогда заголовок меняется на:

class Foo { virtual void g(); virtual void f(); };

А для следующего объектного файла предположения компилятора о том, где f () находится в vtable класса, неверны.

Часто простая перекомпиляция мира (всего!) Поможет.

7 голосов
/ 15 декабря 2008

Это, скорее всего, связано с несовместимыми соглашениями о вызовах, когда у библиотеки и вызывающей стороны разные представления о расположении стека.

Для получения дополнительной информации посмотрите MSDN .

3 голосов
/ 16 декабря 2008
  • Убедитесь, что вы не выбрали в вашем проекте старая версия библиотека, т.е. (как сказал Адам) вы выбрали более старую отладку версия вместо текущей версии версия или наоборот.

  • Возможно, вам потребуется восстановить.

  • Также следите за условной компиляцией, где макрос может получить #defined или # undef'd в какой-то момент (другое решение может иметь некоторые макросы или прогнозируемые #defines). Немного раз может быть полезно удалить ваш .lib .obj, и предварительно скомпилированный кэши заголовков с перестройкой.

  • Существует небольшая вероятность того, что что-то напутано в вашей IDE или конфигурация проекта, где вы может потребоваться воссоздать ваш проект с нуля.

  • Я не слишком знаком с MS VC, можете ли вы добавить проект библиотеки файл из другого решения? За Например, в Borland C ++ Builder вы можно определить группы проектов и построить / сделать несколько проектов, я всегда ставьте проекты для библиотеки, которые я использую в своей программе проектная группа, так что все получает в актуальном состоянии, когда я строю.

2 голосов
/ 15 декабря 2008

Убедитесь, что вы компилируете в режиме отладки, а не в режиме выпуска. Если вы попытаетесь отладить программу в режиме Release, данные, которые вы получите от отладчика, будут мусором из-за оптимизации.

1 голос
/ 15 декабря 2008

Я помню такие вещи, когда выравнивание членов структуры (переключатель компилятора / Zp) двоичных файлов было другим. Вы тоже можете это проверить.

Установка с помощью #pragma pack, а не с помощью настроек проекта, должна быть более безопасной.

...