C++ ユーザーズガイド ホーム目次前ページへ次ページへ索引


第 5 章

ライブラリの使用

ライブラリを使用すると、アプリケーション間でコードを共有したり、非常に大規模なアプリケーションを単純化することができます。Sun WorkShop C++ コンパイラでは、さまざまなライブラリを使用できます。この章では、これらのライブラリの使用方法を説明します。

C ライブラリ

Solaris オペレーティング環境では、いくつかのライブラリが /usr/lib にインストールされます。このライブラリのほとんどは C インタフェースを持っています。デフォルトでは libclibmlibw ライブラリが CC ドライバによってリンクされます。ライブラリ libthread は、-mt オプションを指定した場合にのみリンクされます。それ以外のシステムライブラリをリンクするには、 -l オプションでリンク時に指定する必要があります。たとえば、libdemangle ライブラリをリンクするには、リンク時に -ldemangleCC コマンド行に指定します。

example% CC text.c -ldemangle

Sun Workshop 6 C++ コンパイラには、独自の実行時ライブラリが複数あります。すべての C++ アプリケーションは、CC ドライバによってこれらのライブラリとリンクされます。C++ コンパイラには、次の節に示すようにこれ以外にも便利なライブラリがいくつかあります。

C++ コンパイラ付属のライブラリ

Sun C++ コンパイラには、いくつかのライブラリが添付されています。これらのライブラリには、互換モード (-compat=4) だけで使用できるもの、標準モード (-compat=5) だけで使用できるもの、あるいは両方のモードで使用できるものがあります。libgc ライブラリと libdemangle ライブラリには C インタフェースがあり、どちらのモードでもアプリケーションにリンクできます。

次の表に、Sun C++ コンパイラに添付されるライブラリと、それらを使用できるモードを示します。

表 5-1   C++ コンパイラに添付されるライブラリ
ライブラリ 内容 使用できるモード
libCrun C++ 実行時 -compat=5
libCstd C++ 標準ライブラリ -compat=5
libiostream 従来の iostream -compat=5
libC C++ 実行時、従来の iostream -compat=4
libcomplex 複素数ライブラリ -compat=4
librwtool Tools.h++ 7.0 -compat=4、-compat=5
librwtool_dbg デバック可能な Tools.h++ 7.0 -compat=5
libgc ガベージコレクション C インタフェース
libgc_dbg デバッグ可能なガベージコレクション -compat=4-compat=5
libdemangle 復号化 C インタフェース


C++ライブラリの説明

これらのライブラリについて簡単に説明します。

デフォルトの C++ ライブラリ

これらのライブラリには、CC ドライバによってデフォルトでリンクされるものと、明示的にリンクしなければならないものがあります。標準モードでは、次のライブラリが CC ドライバによってデフォルトでリンクされます。
-lCstd -lCrun -lm -lw -lcx -lc
互換モード (-compat) では、次のライブラリがデフォルトでリンクされます。
-lC -lm -lw -lcx -lc

詳細は、「-library=l[,...l]」を参照してください。

関連するライブラリオプション

CC ドライバには、ライブラリを使用するためのオプションがいくつかあります。

-library オプションと -staticlib オプションの両方に指定されたライブラリは静的にリンクされます。次にオプションの例をいくつか示します。

本来ならデフォルトで使用される libCrun ライブラリと libCstd ライブラリが、リンクされなくなります。

デフォルトでは、CC は、指定されたコマンド行オプションに従ってさまざなシステムライブラリをリンクします。-xnolib (または-nolib) が指定された場合は、-l オプションで明示的に指定されたライブラリだけをリンクします (-xnolib または-nolib が使用された場合は、-library オプションを指定しても無視されます)。

-R オプションは、動的ライブラリの検索パスを実行可能ファイルに組み込むときに使用します。実行時リンカーは、実行時にこれらのパスを使ってアプリケーションに必要な共有ライブラリを探します。CC ドライバは、デフォルトで -R/opt/SUNWspro/libld に渡します (コンパイラが標準の場所にインストールされている場合)。共有ライブラリのデフォルトパスが実行可能ファイルに組み込まれないようにするには、-norunpath を使用します。

クラスライブラリの使用

一般に、クラスライブラリを使用するには 2 つの手順が必要です。

  1. ソースコードに適切なヘッダーをインクルードする。

  2. プログラムをオブジェクトライブラリとリンクする。

iostream ライブラリ

Sun Workshop 6 C++ コンパイラには、2 通りの 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

次の例では、標準の iostream が使用されています。

//ファイル 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=complex
example% a.out
x=(3, 3), y=(4, 4), z=(0, 24)

次は、標準モードでコンパイルされるように ex2.cc と書き直された ex1.cc です。

// ファイル ex2.cc (ex1.cc rewritten for standard mode)
#include <iostream>
#include <complex>
int main()
{
     std::complex<double> x(3,3), y(4,4);
     std::complex<double> z = x * y;
     std::cout << "x=" << x << ", y=" << y << ", z=" << z << 
       std::endl;
}

次の例では、書き直された ex2.cc をコンパイル、リンクして、生成されたプログラムを実行しています。

demo% CC ex2.cc
demo% a.out
x=(3,3), y=(4,4), z=(0,24)

C++ライブラリのリンク

次の表は、C++ ライブラリにリンクするためのコンパイラオプションをまとめています。詳細は、「-library=l[,...l]」を参照してください。

表 5-2   C++ ライブラリにリンクするためのコンパイラオプション
ライブラリ コンパイルモード オプション
従来の iostream -compat=4
-compat=5
不要
-library=iostream
complex -compat=4
-compat=5
-library=complex
不要
Tools.h++ バージョン 7 -compat=4
-compat=5
-library=rwtool7
-library=rwtool7,iostream
デバッグ対応 Tools.h++ バージョン 7 -compat=4
-compat=5
-library=rwtool7_dbg
-library=rwtool7_dbg,iostream
ガベージコレクション -compat=4
-compat=5
-library=gc
-library=gc
デバッグ対応ガベージコレクション -compat=4
-compat=5
-library=gc_dbg
-library=gc_dbg


標準ライブラリの静的リンク

デフォルトでは、CC ドライバは、デフォルトライブラリのそれぞれについて -llib オプションをリンカーに渡すことによって、libclibm などの共有ライブラリをいくつか静的にリンクします (互換性モードと標準モードのデフォルトライブラリについては、「デフォルトの 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 と静的に、libwlibmlibc と動的にリンクする方法を示します。

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 ドライバは、-lthreadld に渡します。これに対し、-mt-xnolib の両方を使用すると、CC ドライバは ld-lthread を渡しません。詳細は、「-xnolib」を参照してください。ld については、Solaris に関するマニュアル『リンカーとライブラリ』を参照してください。

共有ライブラリの使用

C++ コンパイラには、次の共有ライブラリが含まれています。

プログラムにリンクされた各共有オブジェクトは、生成される実行可能ファイル (a.out ファイル) に記録されます。この情報は、実行時に ld.so が使用して動的リンク編集を行います。ライブラリコードをアドレス空間に実際に組み込むのは後になるため、共有ライブラリを使用するプログラムの実行時の動作は、環境の変化 (つまり、ライブラリを別のディレクトリに移動すること) に影響を受けます。たとえば、プログラムが /opt/SUNWspro/release/liblibcomplex.so.5 とリンクされている場合、後で libcomplex.so.5 ライブラリを /opt2/SUNWspro/release/lib に移動すると、このバイナリコードを実行したときに次のメッセージが表示されます。

ld.so.1: a.out: libcomplex.so.5: open に失敗しました: 
ファイルもディレクトリもありません。

ただし、環境変数 LD_BINARY_PATH に新しいライブラリの ディレクトリを設定すれば、古いバイナリコードを再コンパイルせずに実行できます。

C シェルでは次のように入力します。

example% setenv LD_LIBRARY_PATH \
/opt2/SUNWspro/release/lib:${LD_LIBRARY_PATH}

Bourne シェルでは次のように入力します。

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 ライブラリを別のものに置き換える場合は、次の関連するヘッダーも置き換える必要があります。

<algorithm> <bitset> <complex> <deque> <fstream <functional> 
<iomanip> <ios> <iosfwd> <iostream> <istream> <iterator> <limits> 
<list> <locale> <map> <memory> <numeric> <ostream> <queue> <set> 
<sstream> <stack> <stdexcept> <streambuf> <string> <strstream> 
<utility> <valarray> <vector>

ライブラリの置き換え可能な部分は、いわゆる「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) というファイルを参照するものとします。この実装には、次の欠点があります。

こうした問題を解決するため、コンパイラの include ディレクトリには、ヘッダーと同じ名前を持つファイルと、一意の接尾辞 .SUNWCCh を持つ、そのファイルへのシンボリックリンクが含まれています (SUNW はコンパイラに関係するあらゆるパッケージに対する接頭辞、CC は C++ コンパイラの意味、.h はヘッダーファイルの通常の接尾辞)。つまり <string> と指定された場合、コンパイラは <string.SUNWCCh> と書き換え、その名前を検索します。接尾辞付きの名前は、コンパイラ専用の include ディレクトリにだけ存在します。このようにして見つけられたファイルがシンボリックリンクの場合 (通常はそうである)、コンパイラは、エラーメッセージやデバッガの参照でそのリンクを 1 回だけ間接参照し、その参照結果 (この場合は string) をファイル名として使用します。ファイルの依存関係情報を送るときは、接尾辞付きの名前の方が使用されます。

この名前の書き換えは、2 つのバージョンがある 17 個の標準 C ヘッダーと 32 個の標準 C++ヘッダーのいずれかを、パスを指定せずに山括弧 < > に囲んで指定した場合にだけ行われます。山括弧の代わりに引用符が使用されるか、パスが指定されるか、他のヘッダーが指定された場合、名前の書き換えは行われません。

次の表は、よくある書き換え例をまとめています。

表 5-3   ヘッダー検索の例 
ソースコード コンパイラによる検索 注釈
<string> string.SUNWCCh C++ の文字列テンプレート
<cstring> cstring.SUNWCCh C の string.h の C++ 版
<string.h> string.h.SUNWCCh C の string.h
<fcntl.h> fcntl.h 標準 C および C++ヘッダー以外
"string" string 山かっこではなく、二重引用符
<../string> ../string パス指定がある場合


コンパイラが 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 ヘッダーの置き換えはサポートされていません。それでもなお、独自のバージョンの標準ヘッダーを使用したい場合、推奨される手順は次のとおりです。

たとえば、<stdio.h><cstdio> の代替ヘッダーとして stdio.hcstdio を使用したいとします。stdio.hcstdio をディレクトリ /myproject/myhdr に置きます。このディレクトリ内で、次のコマンドを実行します。

example% ln -s stdio.h stdio.h.SUNWCCh
example% ln -s cstdio cstdio.SUNWCCh

コンパイルのたびに、オプション -I/myproject/mydir を使用します。

警告:


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引