Up: Library tips


7.1 Cヘッダファイルを書く

移植性の高いCヘッダファイルを書くことは難しく,それは異なる形式のコン パイラで読まれる可能性があるためです.

C++コンパイラ
C++コンパイラは,Cより強固に形式化されているため,完全なプロトタイプで 宣言された関数を要求します.C関数と変数は,名前がおかしくならないよう に,extern "C"ディレクティブで宣言する必要があります.libtool でC++の使用に関連したその他の問題は,See C++ libraries.
ANSI Cコンパイラ
ANSI Cコンパイラは,C++コンパイラほど厳密ではありませんが,関数のプロ トタイプは,ヘッダファイルを#includeしたときの不必要な警告を避 けるため,行う方が良いでしょう.
非ANSI Cコンパイラ
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のシン ボル名ですが,ヘッダの内容の中心周辺にこれらのマクロの単一の組がある場 合,ヘッダファイルはより管理しやすくなります.

PARAMSBEGIN_C_DECLS,そしてEND_C_DECLSのこれら の定義を独自のヘッダで使用すべきです.そして,C++,ANSI,そして非ANSI のコンパイラ1で有効なヘッダファイルを作成するために,そ れらを使用することが可能となります.

移植可能なコードをネイティブに書かないでください,上記のヒントに続ける ことで,最も明白な問題を無くすことに役立ちますが,明らかに別の微妙な問 題があります.以下の問題に対処する必要があるかもしれません.


脚注

[1] 我々は,__P__BEGIN_DECLSそして __END_DECLSの使用を推奨していました.アンダースコアで始まるシン ボル(とプリプロセッサマクロさえも)がコンパイラの使用で予約されているの で,悪いアドバイスでした.