プロジェクトにライブラリ(.libまたは.aファイル)を追加するには、下図のようにプロジェクトビューに追加するのが一般的な方法です。
単一のプラットフォーム向けにビルドする場合には、この方法でも確かに問題はありませんが、Win32とWin64を同時にビルドするケースや、ツールチェーンのアップグレード(例えば、新しいWin64のモダンC++ツールチェーンへのアップグレード)を行うケースでは、問題が生じます。なぜならば、ライブラリはオブジェクトファイルの集合体であるため、ツールチェーンに大きく依存いたします。
- Win32は、OMF形式のオブジェクト
- 古いWin64は、ELF64形式のオブジェクト
- 新しいWin64は、COFF形式のオブジェクト
例えば、上記のようにそれぞれ使用しているオブジェクト形式が異なります。そのため、あるツーチェーンが別のツールチェーンのオブジェクトを使用することはできません。(例えば、古いWin64はCOFF形式のオブジェクトは使用不可)
さらに、32-bitと64-bitのライブラリを直接プロジェクトに追加すると、いずれかのプラットフォームで実行できないファイルが生成されます。
では、MyLibrary.lib (Win32)、MyLibrary.a (古いWin64)、libMyLibrary.lib (新しいWin64 、下記参照) という3つのライブラリが存在する場合、それぞれに必要なライブラリを適切にリンクするためには、どうすればよいでしょうか。
自動リンクは、ライブラリ名の接頭辞 (上記では「MyLibrary」) を取得し、適切なライブラリを検索してリンクします。
[crayon-6784a4feb6f34744427531/]例えば、ソースコード内に上記のように記述するだけです。
この方法でプロジェクトをビルドする際に、ターゲットプラットホームがWin32の場合は、MyLibrary.libを検索し、古いWin64の場合は、MyLibrary.aを検索します。そして新しいWin64の場合は、複数のバリエーションから検索することができます。なぜならば、通常の静的ライブラリ、DLLインポートライブラリ、パッケージインポートライブラリである可能性があり、.libや.aの接尾辞が付いていたり、あるいは「lib」の接頭辞が付いている可能性もあるからです。バリエーションが多いと自分自身ではその判断に迷うところですが、新しいツールチェーンでは、一致するライブラリが存在する場合は、それを検出して自動的にリンク処理まで行ってくれます。
上記の画面ショットでは、「libvtkCommMath-9.3.dll.a」を直接プロジェクトに追加し、リンクを行っていますが、新しいWin64プラットフォームでは、以下のようにソースコード内で定義します。
[crayon-6784a4feb6f3e438905141/]これによって、「lib」接頭辞と「.dll.a」接尾辞を自動的にチェックして、検出が行われます。
興味深い事実:自動リンクは常に内部で行われています。これは、適切なコンポーネント パッケージがリンクされる仕組みです(なぜなら、パッケージは特別な形式のライブラリ、つまりパッケージ インポートライブラリを介してリンクしているため、自動リンクによってライブラリの判別が可能)。VCL ヘッダーを開くと、各ファイルに自動リンクするpragmaが表示され、パッケージへのリンクが作成されます。
さらに興味深い事実:新しいWin64ツールチェーンでは、インポートライブラリを生成することなく、DLLに直接リンクすることができます。詳しくは次の節を参照してください。
補足事項
言い換えますと、プロジェクトビューからライブラリファイルを削除し、代わりにソースに#pragma comment(lib, “…”)ステートメントを追加します。ただし、リンカがこのpragmaが生成するレコードを認識できるように、確実に使用するヘッダーファイル、または確実にリンクされることが分かっている他のファイルに追加することをお勧めします。(このpragmaが生成するレコードが、コンパイラで使用されない、あるいはコンパイラが不必要と判断し、リンカに認識されない状況は避けてください)
例えば、ライブラリ名に「MyLibrary.abc」というような3 文字の拡張子を付けるのは避けてください。「.abc」をファイル拡張子と見なしてしまい、「.lib」などを追加して類似の名前をテストしません。
通常では、ライブラリ全体をリンクしたい場合が多いでしょう。その場合は、#pragma link を使用してオブジェクトファイルにリンクすることもできます。
最後に、こちらのドキュメントもご覧ください。他の多くのdocwikiページと同様に、新しいWin64向けに更新され、自動リンクの動作について詳しく説明しています。
DLLに直接リンクする
C++Builder 12.2の新しいツールチェーンでは、この非常にクールな新機能によって、DLLへのリンクがこれまで以上に簡単になりました。
かつて、C++Builderの全ライフサイクルにおいて、DLLインポートライブラリを使用することで、アプリケーションをDLLにリンクさせていました。DLLインポートライブラリは、DLL内のメソッドに関する情報を含む小さなライブラリで、Windows で常に行われてきた方法であり、多くのWindows開発者にとっては「標準的」な方法でした。
新しいツールチェーンでは魔法のように、以下の方法でDLLに直接リンクできるようになります。
- ライブラリの検索パスにDLLのコピーがあることを確認してください。
- -lmydllまたは#pragma comment(lib, “mydll”)のどちらかを使用してください。
たったこれだけです。これでDLLが検出され、インポートライブラリを使用しなくてもDLL内のメソッドがアプリケーションで必要とされるようにするすべての魔法が実行されます。
ウェビナーについて
本ブログの内容は、エンバカデロのC++のブロダクトマネージャである「David Millington」が、ウェビナー内で「Tip #6, Handling Libraries with AutoLinking」で解説しています。このウェビナーはC++Builder / RAD Studio 12.2の新しいWin64 モダンツールチェインを活用するためのヒントや非常に有益な情報を紹介しています。もしウェビナー(英語)をご覧になりたい場合は、以下をご参照ください。
「Tip #6, Handling Libraries with AutoLinking」の節は、下記の動画の「1:18:38〜」です。