APIではなく、ライブラリ内でのみ関数を表示する
私はいくつかのファイルに分散されているC99ライブラリを書いています。
// core.h
void my_private_fn();
void API_my_public_fn();
// core.c
#include "core.h"
void my_private_fn() {
do_something();
}
void API_my_public_fn() {
do_something_else();
}
// module_a.h
#include "core.h"
void API_useful_thing();
// module_a.c
#include "module_a.h"
void API_useful_thing() {
my_private_fn();
}
API_
ライブラリを使用するプログラムで接頭辞付きの関数のみを表示したいのですが、で使用するにmy_private_fn
はcore.h
で公開する必要もありmodule_a.c
ます。my_private_fn
ライブラリ内でのみ表示できるようにする方法はCにありますか?
回答
関数が定義されているコンパイルユニットでのみ表示される必要がある場合は、関数を宣言できますstatic
。C言語には可能なスコープがほとんどないため、シンボルは3つのスコープしか持つことができません。
- ブロックにローカル(ブロックは関数または関数内のブロックにすることができます)
- 静的スコープ(関数外の静的宣言):シンボルは、宣言されているコンパイルユニットでのみ表示されます
- グローバルスコープ(関数外の非静的宣言):シンボルはプログラム全体で表示されます。
せいぜい、公式に文書化されたAPIで宣言していないプライベートインクルードファイルで宣言を非表示にすることができます。そうすれば、従順なユーザーはそれを使用すべきではありません。ただし、ユーザーが宣言を独自のコードに入れて関数を使用するのを防ぐことはできません。
ライブラリ内でのみ使用され、エンドユーザーには配布されない内部ヘッダーファイルにそれらを配置しますcore_internal.h
。たとえば、。
私が選択したSergeの回答に基づいて、コード構築をレイアウトするためのより適切な方法を見つけました。その最もメリットがあります。
重要なのは、「プライベート」関数を、ヘッダーファイルではなくCファイルにのみ含まれるヘッダーに配置することです。このようにして、「プライベート」シンボルは内部で使用できますが、外部の呼び出し元では使用できません。完全な例では:
core.h
:
void my_public_fn();
core_priv.h
:
void my_private_fn();
core.c
:
#include <stdio.h>
#include "core.h"
#include "core_priv.h"
void my_private_fn() {
printf("Private function called.\n");
}
void my_public_fn() {
printf("Public function called.\n");
}
module_a.h
:
#include "core.h"
void module_a_fn();
module_a.c
:
#include "core_priv.h"
#include "module_a.h"
void module_a_fn() {
my_private_fn();
my_public_fn();
}
また、必要に応じて、複数のモジュールを共通のライブラリヘッダーにグループ化することもできます。
library.h
:
#include "module_a.h"
// etc.
このように、ライブラリを使用するプログラムは、次のファイルのみを含める必要があります。
main.c
:
#include "library.h"
int main() {
//my_private_fn(); // This triggers a compile warning.
my_public_fn(); // I can still reach the "core" public function.
module_a_fn(); // This calls the "private" function internally.
return 0;
}
コンパイルとyieldのgcc -Wall *.c -o main.o
実行./main.o
:
Public function called.
Private function called.
Public function called.