0

__cdecl呼び出し規約 (msvc2010) を使用してコンパイルされたプロジェクトがあり、デフォルト設定を使用して同じコンパイラを使用してブーストをコンパイルしました。

プロジェクトはブーストにリンクされていましたが、実行時に次のようなアサート メッセージが表示されました: ファイル: ...\boost\boost\program_options\detail\parsers.hpp 行: 79

実行時チェックの失敗 #0 - ESP の値が関数呼び出しで適切に保存されませんでした。これは通常、ある呼び出し規約で宣言された関数を、別の呼び出し規約で宣言された関数ポインターで呼び出した結果です。

次の質問があります。

  • Windows (msvc2010) でデフォルトでビルドをブーストする呼び出し規約
  • __cdecl 呼び出し規約でブーストをコンパイルする方法
  • なぜブーストは異なる呼び出し規約を持つコードとのリンクを防ぐことができなかったのですか? ブーストには本当にスマートなライブラリ自動インクルージョン コードがあることを理解しました。

更新 #1

ブーストは適切な呼び出し規約でコンパイルおよびリンクしているように見えますが、実行時に上記の問題が発生します。同じコードを使用してサンプル アプリケーションを実行しましたが、動作しますが、私のアプリケーションでは失敗します。唯一の違いは、プロジェクト構成または includes/stdafx.h によるものです。

4

3 に答える 3

2

使うだけ

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

ブーストライブラリの構築中。

于 2011-09-09T08:20:01.370 に答える
1

私の知る限り、C++ で cdecl 呼び出し規則を使用する方法はありません ( MSDN Calling Conventionを参照)。C++ メソッドの呼び出しは、C とはまったく異なります。C 呼び出し規則のいずれかを使用する必要がある唯一の機会は、C++ のクラス静的関数を含む関数の場合です。その場合は、ビルド中にオプションを追加して、ビルド時にオプションを強制することができます。

bjam cxxflags=/Gd ...

( BBv2 組み込み機能を参照)

または、「永続的」にするには、コンパイラで user-config.jam をセットアップし、すべての BBv2 msvc ビルドのビルド オプションに追加します ( BBv2 構成および関連ドキュメントを参照)。あなたの他の質問について:

  1. Boost は、MSVC が使用するデフォルトの呼び出し規約を使用しますが、コード レベルでオーバーライドする場合を除きます。それらはライブラリ固有であるため、それらがどこにあるのかわかりません。したがって、「__*」コード デコレータのコードを検索する必要があります。
  2. 部分的な回答については、上記を参照してください。
  3. 検出; 理由は 2 つあります。構築のために合理的に検出できるさまざまなオプションの数には制限があります。これは、考えられるさまざまなバリエーションが指数関数的に増加するため、最も重要なケースに限定するためです。また、呼び出し規約の場合、関数ごとに変更できるものであるため、実際には不可能です。
于 2010-04-24T15:38:30.353 に答える
0

共有プロパティ ファイルの 1 つに問題の原因が見つかりました。<StructMemberAlignment>4Bytes</StructMemberAlignment>

それを削除すると、コードは機能します。それでも、なぜこれが起こっているのか、上記のコードを削除せずにどのように解決できるのかはわかりません (これは別のライブラリで必要でした)。

ブーストと構造体メンバーの配置に関する別の質問を追加しました。

于 2010-04-25T19:29:39.247 に答える