| C++ ユーザーズガイド |
第 5 章
ライブラリの使用
ライブラリを使用すると、アプリケーション間でコードを共有したり、非常に大規模なアプリケーションを単純化することができます。Sun WorkShop C++ コンパイラでは、さまざまなライブラリを使用できます。この章では、これらのライブラリの使用方法を説明します。
C ライブラリ
Solaris オペレーティング環境では、いくつかのライブラリが
/usr/libにインストールされます。このライブラリのほとんどは C インタフェースを持っています。デフォルトではlibc、libm、libwライブラリがCCドライバによってリンクされます。ライブラリlibthreadは、-mtオプションを指定した場合にのみリンクされます。それ以外のシステムライブラリをリンクするには、-lオプションでリンク時に指定する必要があります。たとえば、libdemangleライブラリをリンクするには、リンク時に-ldemangleをCCコマンド行に指定します。
example%CC text.c -ldemangleSun Workshop 6 C++ コンパイラには、独自の実行時ライブラリが複数あります。すべての C++ アプリケーションは、
CCドライバによってこれらのライブラリとリンクされます。C++ コンパイラには、次の節に示すようにこれ以外にも便利なライブラリがいくつかあります。C++ コンパイラ付属のライブラリ
Sun C++ コンパイラには、いくつかのライブラリが添付されています。これらのライブラリには、互換モード (
-compat=4) だけで使用できるもの、標準モード (-compat=5) だけで使用できるもの、あるいは両方のモードで使用できるものがあります。libgcライブラリとlibdemangleライブラリには C インタフェースがあり、どちらのモードでもアプリケーションにリンクできます。次の表に、Sun C++ コンパイラに添付されるライブラリと、それらを使用できるモードを示します。
C++ライブラリの説明
- これらのライブラリについて簡単に説明します。
libCrun:このライブラリには、コンパイラが標準モード (-compat=5) で必要とする実行時サポートが含まれています。newとdelete、例外、RTTI がサポートされます。libCstd:これは C++ 標準ライブラリです。特に、このライブラリにはiostreamが含まれています。既存のソースで従来のiostreamを使用している場合には、ソースを新しいインタフェースに合わせて修正しないと、標準iostreamを使用できません。詳細は、標準 C++ ライブラリのマニュアルを参照してください。libiostream:これは標準モード (-compat=5)で構築した従来のiostreamライブラリです。既存のソースで従来のiostreamを使用している場合には、libiostreamを使用すれば、ソースを修正しなくてもこれらのソースを標準モード (-compat=5) でコンパイルできます。このライブラリを使用するには、-library=iostreamを使用します。libC:これは互換モード (-compat=4) で必要なライブラリです。このライブラリには C++ 実行時サポートだけでなく従来のiostreamも含まれています。libcomplex:このライブラリは、互換モード (-compat=4) で複素数の演算を行うときに必要です。標準モードの場合は、libCstdの複素数演算の機能が使用されます。libwtool:(Tools.h++ 7) これは RougeWave の Tools.h++ バージョン 7 ライブラリです。libgc:これはガベージコレクションライブラリ (Sun WorkShop Memory Monitor の構成要素) です。このライブラリの文書にアクセスするには、Memory Monitor を起動するか、Web ブラウザで次のファイルを参照してください。
file:install-directory/SUNWspro/docs/ja/index.html- install-directory は、Sun WorkShop インストールディレクトリへのパスに変更します。デフォルトのインストールでは、install-directory は
/optです。libdemangle:このライブラリは C++ 符号化名を復号化するときに使用します。デフォルトの C++ ライブラリ
- これらのライブラリには、
CCドライバによってデフォルトでリンクされるものと、明示的にリンクしなければならないものがあります。標準モードでは、次のライブラリがCCドライバによってデフォルトでリンクされます。
-lCstd -lCrun -lm -lw -lcx -lc- 互換モード (
-compat) では、次のライブラリがデフォルトでリンクされます。
-lC -lm -lw -lcx -lc詳細は、「-library=l[,...l]」を参照してください。
関連するライブラリオプション
CC ドライバには、ライブラリを使用するためのオプションがいくつかあります。
- リンクするライブラリを指定するには、
-lオプションを使用します。- ライブラリを検索するディレクトリを指定するには、
-Lオプションを使用します。- Sun C++ コンパイラに添付された次のライブラリを指定するには、
-libraryオプションを使用します。
-libraryオプションと-staticlibオプションの両方に指定されたライブラリは静的にリンクされます。次にオプションの例をいくつか示します。
- 次のコマンドでは Tools.h++ バージョン 7 と
libiostreamライブラリが動的にリンクされます。
example%CC test.cc -library=rwtools7,iostream- 次のコマンドでは
libgcライブラリが静的にリンクされます。
example%CC test.cc -library=gc -staticlib=gc- 次のコマンドでは
test.ccが互換モードでコンパイルされ、libCが静的にリンクされます。互換モードではlibCがデフォルトでリンクされるので、このライブラリを-libraryオプションで指定する必要はありません。
example%CC test.cc -compat=4 -staticlib=libC- 次のコマンドでは ライブラリ
libCrunおよびlibCstdがリンク対象から除外されます。指定しない場合は、これらのライブラリは自動的にリンクされます。
example%CC test.cc -library=no%Crun,no%Cstd本来ならデフォルトで使用される
libCrunライブラリとlibCstdライブラリが、リンクされなくなります。デフォルトでは、
CCは、指定されたコマンド行オプションに従ってさまざなシステムライブラリをリンクします。-xnolib(または-nolib) が指定された場合は、-lオプションで明示的に指定されたライブラリだけをリンクします (-xnolibまたは-nolibが使用された場合は、-libraryオプションを指定しても無視されます)。
-Rオプションは、動的ライブラリの検索パスを実行可能ファイルに組み込むときに使用します。実行時リンカーは、実行時にこれらのパスを使ってアプリケーションに必要な共有ライブラリを探します。CC ドライバは、デフォルトで-R/opt/SUNWspro/libをldに渡します (コンパイラが標準の場所にインストールされている場合)。共有ライブラリのデフォルトパスが実行可能ファイルに組み込まれないようにするには、-norunpathを使用します。クラスライブラリの使用
一般に、クラスライブラリを使用するには 2 つの手順が必要です。
iostreamライブラリSun Workshop 6 C++ コンパイラには、2 通りの
iostreamが実装されています。
- 従来の iostream : この用語は、C++ 4.0、4.0.1、4.1、4.2 コンパイラに添付された
iostreamライブラリ、およびそれ以前にcfrontベースの 3.0.1 コンパイラに添付されたiostreamライブラリを指します。このライブラリの標準はありませんが、既存のコードの多くがこれを使用しています。このライブラリは、互換モードのlibCの一部であり、標準モードのlibiostreamにもあります。- 標準の iostream : これは C++ 標準ライブラリ
libCstdに含まれていて、標準モードだけで使用されます。これは、バイナリレベルでもソースレベルでも「従来のiostream」とは互換性がありません。すでに C++ のソースがある場合、そのコードは従来の
iostreamを使用しており、次の例のような形式になっていると思われます。
// ファイル prog1.cc#include <iostream.h>int main() {cout << "Hello, world!" << endl;return 0;}次のコマンドは、互換性モードで
prog1.ccをコンパイル、リンクして、prog1という実行可能なプログラムを生成します。従来のiostreamライブラリは、互換性モードのときにデフォルトでリンクされるlibCライブラリに含まれています。
example%CC -compat prog1.cc -o prog1
//ファイル prog2.cc#include <iostream>int main() {std::cout << "Hello, world!" << std::endl;return 0;}次のコマンドは、
prog2.ccをコンパイル、リンクして、prog2という実行可能なプログラムを生成します。コンパイルは標準モードで行われ、このモードでは、標準のiostreamライブラリを含むlibCstdがデフォルトでリンクされます。
example%CC prog2.cc -o prog2
complexライブラリ標準ライブラリには、C++ 4.2 コンパイラに付属していた
complexライブラリに似た、テンプレート化されたcomplexライブラリがあります。標準モードでコンパイルする場合は、<complex.h>ではなく、<complex>を使用する必要があります。互換性モードで<complex>を使用することはできません。互換性モードでは、リンク時に
complexライブラリを明示的に指定しなければなりません。標準モードでは、complexライブラリはlibCstdに含まれており、デフォルトでリンクされます。標準モード用の
complex.hヘッダーはありません。C++ 4.2 では、「complex」 はクラス名ですが、標準 C++ では「complex」はテンプレート名です。したがって、旧式のコードを変更せずに動作できるようにする typedef を使用することはできません。このため、複素数を使用する、4.2 用のコードで標準ライブラリを使用するには、多少の編集が必要になります。たとえば、次のコードは 4.2 用に作成されたものであり、互換性モードでコンパイルされます。
// ファイル ex1.cc (互換モード)#include <iostream.h>#include <complex.h>int main(){complex x(3,3), y(4,4);complex z = x * y;cout << "x=" << x << ", y=" << y << ", z=" << z << endl;}次の例では、
ex1.ccを互換モードでコンパイル、リンクし、生成されたプログラムを実行しています。
example%CC -compat ex1.cc -library=complexexample%a.outx=(3, 3), y=(4, 4), z=(0, 24)次は、標準モードでコンパイルされるように
ex2.ccと書き直されたex1.ccです。
次の例では、書き直された
ex2.ccをコンパイル、リンクして、生成されたプログラムを実行しています。
demo%CC ex2.ccdemo%a.outx=(3,3), y=(4,4), z=(0,24)C++ライブラリのリンク
次の表は、C++ ライブラリにリンクするためのコンパイラオプションをまとめています。詳細は、「-library=l[,...l]」を参照してください。
標準ライブラリの静的リンク
デフォルトでは、
CCドライバは、デフォルトライブラリのそれぞれについて-llib オプションをリンカーに渡すことによって、libcやlibmなどの共有ライブラリをいくつか静的にリンクします (互換性モードと標準モードのデフォルトライブラリについては、「デフォルトの C++ ライブラリ」を参照)。このようにデフォルトのライブラリを静的にリンクする場合、
-libraryオプションと-staticlibオプションを一緒に使用すれば、C++ ライブラリを静的にリンクできます。この方法は、以前説明した方法よりもかなり簡単です。次に例を示します。
example%CC test.c -staticlib=Crunこの例では、
-libraryオプションが明示的にコマンドに指定されていません。標準モード (デフォルトのモード) では、-libraryのデフォルトの設定が%none,Cstd,Crunであるため、-libraryオプションを明示的に指定する必要はありません。あるいは、
-xnolibコンパイラオプションも使用できます。-xnolibオプションを指定すると、ドライバは自動的には-lオプションをldに渡しません。-lオプションは、自分で渡す必要があります。次の例は、Solaris 2.6、Solaris 7、Solaris 8 のいずれかのオペレーティング環境でlibCrunと静的に、libw、libm、libcと動的にリンクする方法を示します。
example%CC test.c -xnolib -lCstd -Bstatic -lCrun \
-Bdynamic -lm -lw -lcx -lc
-lオプションの順序は重要です。-lcの前に-lCstd、-lCrun、-lm、-lw、-lcxオプションがあることに注意してください。
注 - IA プラットフォームでは、-lcxオプションはありません。
他のライブラリにリンクする
CCオプションもあります。そうしたライブラリへのリンクも-xnolibによって行われないように設定できます。たとえば、-mtオプションを指定すると、CCドライバは、-lthreadをldに渡します。これに対し、-mtと-xnolibの両方を使用すると、CCドライバはldに-lthreadを渡しません。詳細は、「-xnolib」を参照してください。ldについては、Solaris に関するマニュアル『リンカーとライブラリ』を参照してください。共有ライブラリの使用
C++ コンパイラには、次の共有ライブラリが含まれています。
プログラムにリンクされた各共有オブジェクトは、生成される実行可能ファイル (
a.outファイル) に記録されます。この情報は、実行時にld.soが使用して動的リンク編集を行います。ライブラリコードをアドレス空間に実際に組み込むのは後になるため、共有ライブラリを使用するプログラムの実行時の動作は、環境の変化 (つまり、ライブラリを別のディレクトリに移動すること) に影響を受けます。たとえば、プログラムが/opt/SUNWspro/release/libのlibcomplex.so.5とリンクされている場合、後でlibcomplex.so.5ライブラリを/opt2/SUNWspro/release/libに移動すると、このバイナリコードを実行したときに次のメッセージが表示されます。
ld.so.1: a.out: libcomplex.so.5: open に失敗しました:ファイルもディレクトリもありません。ただし、環境変数
LD_BINARY_PATHに新しいライブラリの ディレクトリを設定すれば、古いバイナリコードを再コンパイルせずに実行できます。
example%setenv LD_LIBRARY_PATH \/opt2/SUNWspro/release/lib:${LD_LIBRARY_PATH}
example$LD_LIBRARY_PATH=\/opt2/SUNWspro/release/lib:${LD_LIBRARY_PATH}example$export LD_LIBRARY_PATH
注 - release には Sun WorkShop の各リリース番号を指定します。
LD_BINARY_PATHには、ディレクトリのリストが含まれています。ディレクトリは通常コロンで区切られています。C++のプログラムを実行すると、動的ローダーがデフォルトディレクトリより前にLD_BINARY_PATHのディレクトリを検索します。実行可能ファイルにどのライブラリが動的にリンクされるのかを知るには、
lddコマンドを使用します。
example%ldd a.out共有ライブラリを移動することはめったにないので、この手順が必要になることはほとんどありません。
注 - 共有ライブラリをdlopenで開く場合は、RTLD_GLOBALを使用しないと例外が機能しません。
共有ライブラリの詳しい使い方については、『リンカーとライブラリ』を参照してください。
C++ 標準ライブラリの置き換え
コンパイラに添付されている標準ライブラリの代わりに別の標準ライブラリを使用することは危険で、必ずしもよい結果にはつながるわけではありません。しかし、パフォーマンス、機能、または他のシステムとの互換性のために異なるバージョンの C++ 標準ライブラリを使用したい場合には、Sun WorkShop 6 C++ で使用するライブラリを変更することができます。基本的な操作としては、コンパイラに添付されている標準のヘッダーとライブラリを無効にして、新しいヘッダーファイルとライブラリが格納されているディレクトリとライブラリ自身の名前を指定します。
置き換える対象
ほとんどの標準ライブラリおよびそれに関連するヘッダーは置き換え可能です。たとえば
libCstdライブラリを別のものに置き換える場合は、次の関連するヘッダーも置き換える必要があります。
ライブラリの置き換え可能な部分は、いわゆる「STL」と呼ばれているもの、文字列クラス、
iostreamクラス、およびそれらの補助クラスです。このようなクラスとヘッダーは相互に依存しているため、それらの一部を置き換えるだけでは通常は機能しません。一部を変更する場合でも、すべてのヘッダーとlibCstdのすべてを置き換える必要があります。標準ヘッダー
<exception>、<new>、および<typeinfo>は、コンパイラ自身とlibCrunに密接に関連しているため、これらを置き換えることは安全ではありません。ライブラリlibCrunは、コンパイラが依存している多くの「補助」関数が含まれているため置き換えることはできません。C から派生した 17 個の標準ヘッダー (
<stdlib.h>、<stdio.h>、<string.h>など) は、Solaris オペレーティング環境と基本 Solaris 実行時ライブラリlibcに密接に関連しているため、これらを置き換えることは安全ではありません。これらのヘッダーの C++ 版 (<cstdlib>、<cstdio>、<cstring>など) は基本の C 版のヘッダーに密接に関連しているため、これらを置き換えることは安全ではありません。代替ライブラリのインストール
代替ライブラリをインストールするには、まず、代替ヘッダーの位置と
libCstdの代わりに使用するライブラリを決定する必要があります。理解しやすくするために、ここでは、ヘッダーを/opt/mycstd/includeにインストールし、ライブラリを/opt/mycstd/libにインストールすると仮定します。ライブラリの名前はlibmyCstd.aであると仮定します。なお、ライブラリの名前をlibで始めると後々便利です。代替ライブラリの使用
コンパイルごとに
-Iオプションを指定して、ヘッダーがインストールされている位置を指示します。さらに、-library=no%Cstdオプションを指定して、コンパイラ独自のバージョンのlibCstdヘッダーが検出されないようにします。次に例を示します。
example%CC -I/opt/mycstd/include -library=no%Cstd ...(コンパイルの場合)
-library=no%Cstdオプションを指定しているため、コンパイル中、コンパイラ独自のバージョンのヘッダーがインストールされているディレクトリは検索されません。プログラムまたはライブラリのリンクごとに
-library=no%Cstdオプションを指定して、コンパイラ独自のlibCstdが検出されないようにします。さらに、-Lオプションを指定して、代替ライブラリがインストールされているディレクトリを指示します。さらに、-lオプションを指定して、代替ライブラリを指定します。次に例を示します。
example%CC -library=no%Cstd -L/opt/mycstd/lib -lmyCstd ...(リンクの場合)あるいは、
-Lや-lオプションを使用せずに、ライブラリの絶対パス名を直接指定することもできます。次に例を示します。
example%CC -library=no%Cstd /opt/mycstd/lib/libmyCstd.a ...(リンクの場合)
-library=no%Cstdオプションを指定しているため、リンク中、コンパイラ独自のバージョンのlibCstdはリンクされません。標準ヘッダーの実装
C には、
<stdio.h>、<string.h>、<stdlib.h>などの 17 個の標準ヘッダーがあります。これらのヘッダーは Solaris オペレーティング環境に標準で付属しており、/user/includeに置かれています。C++ にも同様のヘッダーがありますが、さまざまな宣言の名前が大域の名前空間とstd名前空間の両方に存在するという条件が付加されています。Solaris 8 より前のリリースの Solaris オペレーティング環境の C++ コンパイラでは、/usr/includeディレクトリにあるヘッダーはそのまま残して、独自のバージョンのヘッダーを別に用意しています。また、C++ には、C 標準ヘッダー (
<cstdio>、<cstring>、<cstdlib>など) のそれぞれについても専用のバージョンがあります。C++ 版の C 標準ヘッダーでは、宣言名はstd名前空間にのみ存在します。C++ には、32 個の独自の標準ヘッダー (<string>、<utility>、<iostream>など) も追加されています。標準ヘッダーの実装で、C++ ソースコード内の名前がインクルードするテキストファイル名として使用されているとしましょう。たとえば、標準ヘッダーの
<string>(または<string.h>) が、あるディレクトリにあるstring(またはstring.h) というファイルを参照するものとします。この実装には、次の欠点があります。
- ファイル名に接尾辞がない場合、ヘッダーファイルだけ検索したり、ヘッダーファイル用のメークファイルを作成したりできない
- コンパイラのコマンド行に
-I/usr/includeを指定すると、コンパイラ専用のincludeディレクトリの前に/usr/includeが検索されるため、Solaris 2.6 および Solaris 7 オペレーティング環境の正しいバージョンの標準 C ヘッダーが検出されないstringというディレクトリまたは実行可能プログラムがあると、そのディレクトリまたはプログラムが標準ヘッダーファイルの代わりに検出される可能性がある- Solaris 8 より前のリリースの Solaris オペレーティング環境では .
KEEP_STATEが有効なときのメークファイルのデフォルトの相互依存関係により、標準ヘッダーが実行可能プログラムに置き換えられる可能性があるこうした問題を解決するため、コンパイラの
includeディレクトリには、ヘッダーと同じ名前を持つファイルと、一意の接尾辞 .SUNWCChを持つ、そのファイルへのシンボリックリンクが含まれています (SUNWはコンパイラに関係するあらゆるパッケージに対する接頭辞、CCは C++ コンパイラの意味、.hはヘッダーファイルの通常の接尾辞)。つまり<string>と指定された場合、コンパイラは<string.SUNWCCh>と書き換え、その名前を検索します。接尾辞付きの名前は、コンパイラ専用のincludeディレクトリにだけ存在します。このようにして見つけられたファイルがシンボリックリンクの場合 (通常はそうである)、コンパイラは、エラーメッセージやデバッガの参照でそのリンクを 1 回だけ間接参照し、その参照結果 (この場合はstring) をファイル名として使用します。ファイルの依存関係情報を送るときは、接尾辞付きの名前の方が使用されます。この名前の書き換えは、2 つのバージョンがある 17 個の標準 C ヘッダーと 32 個の標準 C++ヘッダーのいずれかを、パスを指定せずに山括弧 < > に囲んで指定した場合にだけ行われます。山括弧の代わりに引用符が使用されるか、パスが指定されるか、他のヘッダーが指定された場合、名前の書き換えは行われません。
コンパイラが header
.SUNWCCh(header はヘッダー名) を見つけることができなかった場合、コンパイラは、#include指令で指定された名前で検索をやり直します。たとえば、#include <string>という指令を指定した場合、コンパイラはstring.SUNWCChという名前のファイルを見つけようとします。この検索が失敗した場合、コンパイラはstringという名前のファイルを探します。標準 C++ ヘッダーの置き換え
「標準ヘッダーの実装」で説明している検索アルゴリズムのため、「代替ライブラリのインストール」で説明している
SUNWCCh版の代替ヘッダーを指定する必要はありません。しかし、これまでに説明したいくつかの問題が発生する可能性もあります。その場合、推奨される解決方法は、接尾辞が付いていないヘッダーごとに、接尾辞.SUNWCChを持つファイルに対してシンボリックリンクを作成することです。つまり、ファイルがutilityの場合、次のコマンドを実行します。
example%ln -s utility utility.SUNWCCh
utility.SUNWCChというファイルを探すとき、コンパイラは 1 回目の検索でこのファイルを見つけます。そのため、utilityという名前の他のファイルやディレクトリを誤って検出してしまうことはありません。標準 C ヘッダーの置き換え
標準 C ヘッダーの置き換えはサポートされていません。それでもなお、独自のバージョンの標準ヘッダーを使用したい場合、推奨される手順は次のとおりです。
- すべての代替ヘッダーを 1 つのディレクトリに置きます。
- そのディレクトリ内にある代替ヘッダーごとに header
.SUNWCCh(header はヘッダー名) へのシンボリックリンクを作成します。- コンパイラを呼び出すごとに
-I指令を指定して、代替ヘッダーが置かれているディレクトリが検索されるようにします。たとえば、
<stdio.h>と<cstdio>の代替ヘッダーとしてstdio.hとcstdioを使用したいとします。stdio.hとcstdioをディレクトリ/myproject/myhdrに置きます。このディレクトリ内で、次のコマンドを実行します。
example%ln -s stdio.h stdio.h.SUNWCChexample%ln -s cstdio cstdio.SUNWCChコンパイルのたびに、オプション
-I/myproject/mydirを使用します。警告:
|
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |