libtwitter-glib のソースコードを読んでたら、C でカプセル化するスマートな方法みたいなのがあったのでメモしておく。*1
まず、ヘッダの方に構造体を宣言するが、外部に見せる構造体 (User) のメンバは内部のプライベートな構造体 (UserPrivate) のポインタのみにしておく。
typedef struct User_ User; typedef struct UserPrivate_ UserPrivate; struct User_ { UserPrivate* priv; }; int user_get_id (User* user); char* user_get_name(User* user);
ソースファイルの方で内部のプライベートな構造体と各メンバへのアクセッサを用意する。
struct UserPrivate_ { int id; char* name; }; int user_get_id(User* user) { return user->priv->id; } char* user_get_name(User* user) { return user->priv->name; }
このようにすると各メンバへのアクセスはアクセッサを使う以外に方法がなくなる。命名規約を決めておけば、自動生成も簡単にできそうな気がする。
今までは MPI の MPI_Info のようなハッシュテーブル風なインタフェースで実装する方法がベタだと思っていたけど、こっちの方が良さげ。
*1:もしかしたら glib/gobject で定石なのかもしれないけど。