Как мне скомпилировать boost, используя соглашение о вызовах __cdecl?

У меня есть проект, скомпилированный с использованием __cdecl соглашение о вызовах (msvc2010) и я скомпилировали boost, используя тот же компилятор, используя настройки по умолчанию.

Проект связан с Boost, но я во время выполнения получил сообщение об утверждении, подобное этому: File: ...\boost\boost\program_options\detail\parsers.hpp Строка: 79

Ошибка проверки времени выполнения #0 - значение ESP не было должным образом сохранено при вызове функции. Это обычно является результатом вызова функции, объявленной с одним соглашением о вызовах с указателем функции, объявленным с другим соглашением о вызовах.

Есть следующие вопросы:

  • какое соглашение о вызовах ускоряет сборку по умолчанию в Windows (msvc2010)
  • как мне скомпилировать boost с __cdecl
  • почему boost не смог предотвратить соединение с кодом с другими соглашениями о вызовах? Я понял, что boost имеет действительно умный код автоматического включения библиотеки.

Обновление № 1

Похоже, что Boost компилирует и связывает с соответствующим соглашением о вызовах, но все же во время выполнения я получаю вышеуказанную проблему. Я сделал пример приложения, используя тот же код, и он работает, но в моем приложении это не удается. Единственное отличие может быть от конфигурации проекта или включает /stdafx.h

3 ответа

Решение

Я нашел причину проблемы в одном из файлов общих свойств: <StructMemberAlignment>4Bytes</StructMemberAlignment>

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

Я добавил еще один вопрос, касающийся усиления и выравнивания элементов конструкции.

Просто используйте

bjam ... **cxxflags=/Zp4**

при создании буст библиотеки.

Насколько я знаю, нет способа заставить C++ использовать соглашения о вызовах cdecl (см. MSDN Calling Convention). Вызов метода C++ просто отличается от C. Единственная возможность использовать одно из соглашений о вызовах C - это функции, которые включают статические функции класса в C++. Если вы знаете, что это так, вы можете попытаться принудительно включить параметр при сборке, добавив его во время сборки:

bjam cxxflags = / Gd...

(см. встроенные функции BBv2)

Или чтобы сделать его "постоянным", настройте user-config.jam с вашим компилятором и добавьте его в параметры сборки для всех сборок BBv2 msvc (см. Конфигурация BBv2 и соответствующие документы). Что касается вас, другие вопросы:

  1. Boost использует соглашение о вызовах по умолчанию, используемое MSVC, за исключением случаев, когда оно переопределяет его на уровне кода. Я не знаю, где они, так как они специфичны для конкретной библиотеки. Поэтому вам придется искать код для "__*" декораторов кода.
  2. Смотрите выше для частичного ответа.
  3. Обнаружение; Есть две причины: существует ограничение на количество различных вариантов, которые мы можем разумно определить для строительства, поскольку это экспоненциальный рост различных возможных вариантов, поэтому мы ограничиваем его наиболее важными случаями. А в случае соглашения о вызовах это на самом деле невозможно, поскольку это то, что можно изменить для каждой функции.
Другие вопросы по тегам