# funcman_libbase の概要

# 1 役割

`funcman_libbase.h` / `funcman_libbase.c` は、`libbase` ライブラリが管理するオーバーライド対応関数の funcman_object 実体と、それに紐付く型・変数の宣言 を提供します。

`funcman` の汎用機能 (`funcman_init`, `_funcman_get_func`, `funcman_dispose` など) は `libbase.h` で定義されています。`funcman_libbase.h` / `funcman_libbase.c` はそれを `libbase` 固有の関数群に接続する「接着剤」の役割を担います。

# 2 ファイルの責務

ファイル | 責務
--- | ---
`funcman_libbase.h` | 関数ポインタ型の `typedef`、`funcman_object` ポインタ・配列・設定ファイルパスの `extern` 宣言
`funcman_libbase.c` | `funcman_object` 実体の定義、配列・要素数・設定ファイルパスの実体定義、`funcman_info_libbase()` の実装

`funcman_object` の実体は `funcman_libbase.c` 内で `static` 変数として定義します。外部からのアクセスは `funcman_object *const` ポインタ経由に限定することで、直接書き換えを防いでいます。

# 3 利用側との関係

    sample_func.c  (呼び出し元)
        |  funcman_get_func(pfo_sample_func, sample_func_t)
        +---> funcman_libbase.h の extern 宣言 (pfo_sample_func)
                  |
                  funcman_libbase.c の実体 (sfo_sample_func)

    dllmain_libbase.c  (初期化・解放)
        |  funcman_init(fobj_array_libbase, fobj_length_libbase, funcman_configpath)
        |  funcman_dispose(fobj_array_libbase, fobj_length_libbase)
        +---> funcman_libbase.h の extern 宣言 (fobj_array_libbase, fobj_length_libbase, funcman_configpath)
                  |
                  funcman_libbase.c の実体

# 4 オーバーライド対応関数を追加する場合の作業

`sample_func` に相当する新しい関数 `new_func` を追加する場合の手順です。

## 4.1 1. `funcman_libbase.h` への追加

以下の 2 点を追記します。

- `new_func` に対応する関数ポインタ型の `typedef`
- その funcman_object へのポインタの `extern` 宣言

## 4.2 2. `funcman_libbase.c` への追加

以下の 2 点を追記します。

- `NEW_FUNCMAN_OBJECT` マクロで funcman_object の `static` 実体を定義し、対応する `const` ポインタを定義
- `fobj_array_libbase` 配列に新しい実体のアドレスを追加

`fobj_length_libbase` は配列サイズから自動計算されるため変更不要です。

## 4.3 3. 呼び出し元となる .c ファイルの作成・修正

`new_func` の実装ファイルで、`funcman_get_func` を使って関数ポインタを取得し、オーバーライド処理またはデフォルト処理に分岐させます。`sample_func.c` を参考にしてください。

## 4.4 4. オーバーライド側ライブラリへの追加

`liboverride` 側 (または別のオーバーライドライブラリ) に、`new_func` と同じシグネチャを持つ実装関数を追加します。

> 警告: 循環参照によるスタックオーバーフロー

> オーバーライド実装の中で、オーバーライド元の関数 (`new_func`) を直接または間接的に呼び出すと無限再帰となりスタックオーバーフローが発生します。

>     new_func (libbase)
>       └─ funcman_get_func でオーバーライド関数を取得
>            └─ new_override_func (liboverride) を呼び出す
>                  └─ new_func (libbase) を呼び出す  ← 無限再帰

> オーバーライド実装はオーバーライド元の関数を呼ばないよう設計してください。同様に、複数の関数をオーバーライドする場合、A のオーバーライドが B を呼び、B のオーバーライドが A を呼ぶような間接的な循環にも注意が必要です。関数を追加する際は、呼び出し経路全体を把握したうえで設計してください。

## 4.5 変更ファイルのまとめ

ファイル | 作業
--- | ---
`funcman_libbase.h` | 型定義・extern 宣言を追加
`funcman_libbase.c` | 実体定義・配列エントリを追加
`libsrc/base/new_func.c` (新規) | funcman を使ったオーバーライド対応の実装
`libsrc/override/new_override_func.c` (新規) | オーバーライド実装
`include/libbase.h` | `new_func` のエクスポート宣言を追加
`include/libbase_ext.h` | オーバーライド関数のエクスポート宣言を追加