Perlテックブログ

ITエンジニアの成長意欲を刺激する技術考察、モジュール開発の日記。Perlイベントや国内や海外のPerlの記事の紹介。

実行時になるまで呼び出す関数が存在するかどうかわからない共有ライブラリにおける関数チェック

C言語の関数呼び出しは、すべて静的なものだと思っていた時期が僕にもありました。

でも関数ポインタを使えば、関数を動的に呼び出すことができます。

void* func_address = &foo;
(*func_address)();

コンパイル時に、すべての関数名を静的にチェックすることができれば、それが一番簡単です。リンカが自動的に名前解決してくれます。

実行時に関数のシグネチャをチェックすべき場合とは

実行時に名前をチェックしないと、非常に危険な場合を考えてみましょう。

たとえば、引数がふたつの関数を動的に呼び出して、これをコンパイルしたとしましょ。

でも、その後、その関数の定義が変更されて、引数が一つになったとしましょ。

関数のシグネチャが入れ替わっているのに、コンパイルされたコードでは、関数の引数がひとつだけ渡されます。第二引数は、不正な値になっているでしょう。

こんな場合は、実行時に関数のシグネチャをチェックしないといけませんね。関数と、それ以外では、フィールド呼び出しと、グローバル変数の呼び出しが、名前を持っているので、チェックしないといけませんね。

名前がそもそも変わってしまった場合と、型が変わってしまった場合には、実行時エラーを吐き出すコードを追加しておくと安全です。

パフォーマンスに影響がでるので、関数の先頭部分でまとめてチェックして、一度チェックした場合はキャッシュすることで、パフォーマンス低下の影響を減らすことができそうです。