Jadikan fungsi hanya terlihat di dalam perpustakaan, bukan di API
Saya menulis pustaka C99 yang didistribusikan di antara beberapa file, mis
// 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();
}
Saya hanya menginginkan API_
fungsi diawali akan terlihat oleh program menggunakan perpustakaan, tapi saya juga perlu untuk mengekspos my_private_fn
di core.h
agar dapat digunakan oleh module_a.c
. Apakah ada cara di C untuk membuat my_private_fn
hanya terlihat di dalam perpustakaan?
Jawaban
Jika fungsi harus hanya terlihat di unit kompilasi tempat ia didefinisikan, maka Anda bisa mendeklarasikannya static
. Karena bahasa C menawarkan sedikit kemungkinan cakupan: simbol hanya dapat memiliki 3 cakupan:
- lokal ke blok (blok bisa menjadi fungsi atau blok di dalam fungsi)
- ruang lingkup statis (deklarasi statis di luar fungsi): simbol hanya terlihat di unit kompilasi tempat ia dideklarasikan
- cakupan global (deklarasi non-statis di luar suatu fungsi): simbol terlihat di seluruh program.
Anda paling banyak dapat menyembunyikan deklarasi dalam file include pribadi yang tidak dideklarasikan di API resmi yang didokumentasikan. Dengan cara itu, pengguna yang patuh tidak boleh menggunakannya. Tetapi Anda tidak dapat mencegah pengguna untuk meletakkan deklarasi dalam kode mereka sendiri dan menggunakan fungsinya.
Letakkan di file header internal yang hanya digunakan di dalam pustaka dan tidak didistribusikan ke pengguna akhir — misalnya core_internal.h
,.
Saya menemukan cara yang lebih rapi untuk menyusun kode saya berdasarkan jawaban Serge yang saya pilih, yang manfaatnya paling banyak diberikan.
Kuncinya adalah meletakkan fungsi "pribadi" di header yang hanya disertakan dalam file C, bukan di file header. Dengan cara ini simbol "pribadi" tersedia secara internal tetapi tidak untuk pemanggil eksternal. Dalam contoh lengkap:
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();
}
Dan jika kita mau, kita bisa mengelompokkan beberapa modul dalam header library umum.
library.h
:
#include "module_a.h"
// etc.
Dengan cara ini, program yang menggunakan pustaka hanya perlu menyertakan satu file dengan hanya:
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;
}
Mengompilasi dengan gcc -Wall *.c -o main.o
dan menjalankan ./main.o
hasil:
Public function called.
Private function called.
Public function called.