こんにちは、高木です。
前回に引き続き、PHPでC言語の前処理を行う話題です。今回は、構造体のメンバーをPHPの配列として定義しておいて、それをC言語のソースコードに変換してみようと思います。
早速、PHPのコードから見ていきましょう。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php $person_type = [ 'name' => [ 'char', 32 ], 'age' => 'int', ]; function make_struct(string $name, array $type): string { $r = "typedef struct {\n"; foreach ($type as $key => $value) { $r .= "\t"; if (is_array($value)) { $r .= "{$value[0]} {$key}[{$value[1]}];\n"; } else { $r .= "$value $key;\n"; } } $r .= "} $name;\n"; return $r; } ?> |
いきなり難しいことをやっても仕方ないので、今回はnameとageという2つのメンバーだけを持つ構造体を作ることにします。nameはchar型の32要素を持つ配列で、ageはint型ということにしました。
上のソースコードで定義したmake_structという関数に、構造体の名前とデータ構造を定義した配列を渡してあげれば、C言語のソースコードを文字列として返します。あとはその文字列をechoなどで出力すればC言語のソースコードに埋め込むことができます。
では、こんなことをして何が嬉しいのでしょうか?
C言語にはリフレクションがありません。構造体の情報を実行時に取得しようと思ってもできませんので、コンパイル時にすべて解決しなければなりません。それ自体はどうしようもないのですが、PHPで前処理を行うことで、ベタベタなハードコーディングからは解放されます。
それを利用すれば、構造体メンバーの値を順に出力することもできますし、シリアライズすることもできます。シリアライズができれば、単純なバイナリデータだけでなくXMLやJSONなどの形式でファイルに読み書きすることもできます。異なるノード間で通信することもできます。
さらには、構造体の内容がわかっていますから、たとえばC#でDllImportして使うための(C#の)構造体定義を出力することもできます。ネットワークなどを通じて他の言語で実装されたプログラムとデータの受け渡しをするためのマーシャラーを自動生成することもできます。
このようにさまざまな可能性が生まれます。今後は、PHPによる前処理のもっと具体的な使い方を紹介していきたいと思います。