4

数か月にわたって、50 奇数のヘッダー/ソース ファイルをインポートするのではなく、ライブラリとしてビルドして動的にリンクしたい、十分に汎用的な機能をいくつか作成しました。

プロジェクトは Xcode と Dev-C++ で管理されており (自分のやりたいことを実行するにはコマンド ラインを使用する必要があるかもしれないことは理解しています)、OpenGL と SDL にリンクする必要があります (SDL の場合は動的に)。ターゲット プラットフォームは Windows と OS X です。

私は一体何を見ているのでしょうか?

  • ライブラリが必要な場合、ライブラリのエントリ ポイントは何になりますか?
  • コードで何を変更する必要がありますか? (呼び出し規約?)
  • どうすれば解放できますか?私の理解では、ヘッダーとコンパイルされたライブラリ (.dll、.dylib(、.framework)、それが何であれ) をプロジェクトで使用できるようにする必要があります。特に、テンプレート機能は本質的にライブラリに含めることができないためです。
  • 他に何を知っておく必要がありますか?
4

3 に答える 3

11

DLL ではなく、statc ライブラリとしてビルドすることをお勧めします。これを行うと、C++ の関数とクラスをエクスポートする際の問題の多くはなくなります。ただし、ライブラリをビルドしたのと同じコンパイラで生成されたコードとのみリンクする場合に限ります。

.o/.obj ファイルの単なるコレクションであるため、スタティック ライブラリの構築は非常に簡単です。ZIP ファイルに少し似ていますが、圧縮されていません。何もエクスポートする必要はありません。アプリケーションがリンクするファイルのリストにライブラリを含めるだけです。特定の関数またはクラスにアクセスするには、関連するヘッダー ファイルを含めるだけです。ヘッダー ファイルを取り除くことはできないことに注意してください。特にテンプレートの C++ コンパイル モデルはヘッダー ファイルに依存しています。

于 2009-05-29T17:55:17.433 に答える
2

動的ライブラリから C++ クラス ライブラリをエクスポートするのは問題になる可能性がありますが、可能です。
DLL からエクスポートする各関数をマークする必要があります (構文はコンパイラによって異なります)。xcodeからこれを行う方法を見つけることができるかどうかを調べています。VC では __declspec(dllexport) で、CodeWarrior では #pragma export on/#pragma export off です。

バイナリを社内でのみ使用している場合、これは完全に合理的です。ただし、1 つの問題は、C++ メソッドの名前がコンパイラによって異なることです。これは、C 関数のみをエクスポートしない限り、別のコンパイラを使用する誰もあなたの DLL を使用できないことを意味します。

また、呼び出し規約が DLL と DLL のクライアントで一致していることを確認する必要があります。これは、DLL とクライアントの両方に対して同じ既定の呼び出し規約フラグをコンパイラに渡す必要があることを意味します。または、DLL 内のエクスポートされた関数ごとに呼び出し規約を明示的に設定することをお勧めします。クライアントのためです。

この記事では、命名の問題について説明しています: http://en.wikipedia.org/wiki/Name_decoration

于 2009-05-29T17:10:55.523 に答える
1

C++ 標準では標準 ABI が定義されていません。これは、C++ ライブラリを構築しようとしている人にとっては悪いニュースです。これは、コンパイルに使用されたフラグに応じて、コンパイルされたコードから異なる動作が得られることを意味し、コンパイルとリンクが正常に行われるコードに謎のバグが発生する可能性があります。

これは、さまざまな呼び出し規約にとどまらず、C++ コードをコンパイルして、RTTI、例外処理、および C++ コードが依存するクラス インスタンスのメモリ レイアウトに影響を与える可能性のあるさまざまな最適化をサポートまたはサポートしないようにすることができます。

それで、あなたは何ができますか?ソース ツリー内に C++ ライブラリをビルドし、それらがプロジェクトのビルドの一部としてビルドされていること、およびすべてのライブラリとそれらにリンクするコードが同じコンパイラ フラグを使用していることを確認します。

少なくとも異なるコンパイラ/コンパイラフラグでコンパイルされたオブジェクトファイルをリンクすることを防ぐはずだった名前マングリングは、ほとんどの場合のみ機能し、特にGCCで実行できる特定のことがあり、リンクするコードが生成されます。問題なく、実行時に失敗します。

ベンダー提供の動的 C++ ライブラリ (たとえば、ほとんどの Linux ディストリビューションの QT) には特に注意する必要があります。ベンダー提供のライブラリが、特定の動作を妨げるような方法でコンパイルされた例を見たことがあります。たとえば、一部の Redhat Linux リリース (おそらくすべて) では、QT で例外が無効化されていたため、QT コールバックで例外がスローされた場合、main() で例外をキャッチできませんでした。楽しい。

于 2009-05-29T18:14:05.617 に答える