[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
良いライブラリインターフェースと書くことは,多くの経験とライブラリが解決 する問題への完全な理解が必要です.
良いインターフェースを設計した場合,頻繁に変更する必要がなく,ドキュメン トを更新し続ける必要がなく,ユーザはライブラリの使用方法を何度も学習する 必要がありません.
ここにライブラリインターフェースの設計に関するヒントの短いリストがあり, それは仕事上で役立つでしょう.
エントリポイントを頻繁に削除する必要がないように,すべてのインターフェー スを本当に最小限にするように試みてください.
エントリポイントの再設計と変更を地獄のように繰り返すのが好きな人もいます (注意:関数の名前変更はエントリポイントの変更と考えられます).イ ンターフェースを再設計する必要がある場合,ユーザが既存のコードを書き換え る必要がないように,互換機能を残すことを試みてください.
ライブラリユーザがアクセスするデータ型の定義は,少ないければ少ないほど良 いでしょう.可能な場合,一般的な(内部データにキャスト可能な)ポインタを受 け入れる関数を設計し,ライブラリユーザが直接データを操作するのを許可する のではなく,アクセスする関数を提供してください.そうすることで,インター フェースを変更せずに,データ構造を変更することが自由になります.
これは,本質的にオブジェクト指向のシステムで抽象的なデータ型と継承を使用 するのと同じです.
ライブラリのグローバル関数と変数のそれぞれのドキュメントをヘッダファイル に注意して書いていて,ライブラリソースファイルに含めている場合,コンパイ ラは偶然にインターフェースの変更の有無を知らせるでしょう(see section Cヘッダファイルを書く).
static
キーワード(またはその等価物)の使用ライブラリが持つグローバル関数は,減らせば減らすほど,より柔軟に変更でき ます.スタティック関数と変数は,形式を変更したいとき変更できます… ユーザはそれらにアクセスできず,そのためインターフェースは変更されません.
7.1 Cヘッダファイルを書く | How to write portable include files. |
移植性の高いCヘッダファイルを書くことは難しく,それは異なる形式のコンパ イラで読まれる可能性があるためです.
C++コンパイラは,Cより強固に形式化されているため,完全なプロトタイプで宣
言された関数を要求します.C関数と変数は,名前がおかしくならないように,
extern "C"
ディレクティブで宣言する必要があります.libtool でC++の
使用に関連したその他の問題は,See section C++に対するライブラリを書く.
ANSI Cコンパイラは,C++コンパイラほど厳密ではありませんが,関数のプロト
タイプは,ヘッダファイルを#include
したときの不必要な警告を避ける
ため,行う方が良いでしょう.
Non-ANSIコンパイラは,関数がプロトタイプされている場合,エラーを報告しま す.
これらの複雑さは,上記それぞれのコンパイラを利用可能にするため,ライブラ リインファーフェースヘッダで,いくつかのCプリプロセッサの魔法を使用する 必要があることを意味します.
libtool配布物の`demo'サブディレクトリの`foo.h'は,安全にシステ ムディレクトリにインストール可能な,ヘッダファイルの書き方の例を提供しま す.
そのファイルの関連する部分は,以下のようになっています.
/* BEGIN_C_DECLS should be used at the beginning of your declarations, so that C++ compilers don't mangle their names. Use END_C_DECLS at the end of C declarations. */ #undef BEGIN_C_DECLS #undef END_C_DECLS #ifdef __cplusplus # define BEGIN_C_DECLS extern "C" { # define END_C_DECLS } #else # define BEGIN_C_DECLS /* empty */ # define END_C_DECLS /* empty */ #endif /* PARAMS is a macro used to wrap function prototypes, so that compilers that don't understand ANSI C prototypes still work, and ANSI C compilers can issue warnings about type mismatches. */ #undef PARAMS #if defined (__STDC__) || defined (_AIX) \ || (defined (__mips) && defined (_SYSTYPE_SVR4)) \ || defined(WIN32) || defined(__cplusplus) # define PARAMS(protos) protos #else # define PARAMS(protos) () #endif |
これらのマクロは,以下のように`foo.h'で使用されます.
#ifndef FOO_H #define FOO_H 1 /* The above macro definitions. */ #include "…" BEGIN_C_DECLS int foo PARAMS((void)); int hello PARAMS((void)); END_C_DECLS #endif /* !FOO_H */ |
`#ifndef FOO_H'が,`foo.h'の本体を,与えられたコンパイルで一回 以上読み込むことを避けることに注意してください.
また,BEGIN_C_DECLS
/END_C_DECLS
の組の外側あるものだけが,
#include
行にあります.厳密にいうと,それは,保護が必要なCのシンボ
ル名ですが,ヘッダの内容の中心周辺にこれらのマクロの単一の組がある場合,
ヘッダファイルはより管理しやすくなります.
PARAMS
,BEGIN_C_DECLS
,そしてEND_C_DECLS
のこれらの
定義を独自のヘッダで使用すべきです.そして,C++,ANSI,そして非ANSIのコ
ンパイラ(7)で有効なヘッダファイルを作成するために,それらを
使用することが可能となります.
移植可能なコードをネイティブに書かないでください,上記のヒントに続けるこ とで,最も明白な問題を無くすことに役立ちますが,明らかに別の微妙な問題が あります.以下の問題に対処する必要があるかもしれません.
ANSI以前のコンパイラは,一般的なポインタ型void *
を常にサポートす
るわけではなく,そこではchar *
を使用する必要があります.
const
,signed
そしてsigned
キーワードは,サポートされ
ていないコンパイラもあり,特にANSI以前のコンパイラがあげられます.
long double
型は,多くのコンパイラでサポートされていません.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.