本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは上川慶さんで、テーマは「Cを用いたPerl拡張入門」です。
本稿のサンプルコードは、本誌「WEB+DB PRESS Vol.108」のサポートサイトから入手できます。
Cを用いたPerl拡張入門
筆者たちPerl Mongerは先人たちが築き上げてきたモジュールを使いながらPerl製のプログラムを作成します。しかしながら、すべてのモジュールがPerlだけで作成されているわけではありません。中にはCの力を借りてPerlの拡張を行っているものもあります。
Cを用いてPerlを拡張する理由
ではなぜ、Cを用いてPerlを拡張する必要があるのでしょうか。それには次の点が挙げられるでしょう。
ホットスポットの改善
ホットスポットとは、処理の中でとても時間がかかっている部分を指します。みなさんが今までにPerlで記述した処理の中には、Perlゆえにパフォーマンスが落ちた処理があるはずです。そのような箇所をCで書きなおすことで、パフォーマンスを改善できます。
Perlゆえにパフォーマンスが落ちる処理について、詳しくは後述します。
ライブラリとのCバインディング
たとえばある画像をPerlから簡単かつ高速に処理したい場合、ImageMagickとCバインディング[1]を行うことで、ImageMagickの機能をPerlのコードとして表現できます。このCバインディングは、Image::Magickというモジュールですでに実現されています。
Cを用いてPerlを拡張する方法
Cを用いてPerlを拡張する方法は2つあります。一つは、PerlのAPIをCのマクロでラップしたXSという言語[2]を用いる方法です。もう一つは、Inline::Cモジュールを用いてPerlコード内に直接Cの関数を記述する方法です。
XSはCで作成した関数をPerlから呼び出すインタフェースとしての役割を持ちます。主にXSモジュールを作成するために用いられ、.xs
ファイルへ記述します。記述したCの関数をPerlで呼び出すために、XSLoaderというモジュールを.pm
ファイル内で利用してCの関数をロードします。
Inline::CはPerlでCを記述するために利用されるモジュールです。そのためXSとは対照的にモジュール化を必要とせず、CのコードをPerlのソースコード上に記述できます。Inline::Cは主に実行するスクリプトやアプリケーションに記述して使用します。
本稿ではXSモジュールを作成するための準備として、PerlとCが連携できるようなコードの書き方を学んでいきます。コードの書き方を集中して学ぶために、XSモジュールの作成はせずに、簡単に編集や実行結果の確認が行えるよう、Inline::CをPerlのスクリプト上で用います。また、本稿の最後に次のステップとして、XSモジュールを作成するために参考になるモジュールやドキュメントを紹介します。
Perlの内部で扱われる型の世界
Cで拡張するために避けて通れないのが型の世界です。なぜなら、CはPerlと違って型を厳密に扱う言語だからです。また、PerlはCで開発されているため、Perl上で表現される値すべてに内部では型が定義されています。
たとえばPerl上でよく表現されるデータタイプとしてスカラがあります。スカラは次のように表現されるものです。
Perlの内部でスカラは、1つの値を格納するSV(Scalar Value)型として定義されています。
必要最小限の基本型を理解する
Cを用いてPerlを拡張するために最小限に理解しておいたほうがよい型が、先ほどのSVです。Perlの内部で定義されている型は、すべてSVと関係を持ちます。たとえば配列を表すAV(Array Value)や連想配列を表すHV(Hash Value)は、SVから派生した(is-a関係を持つ)型です。そのため、AV、HVからSVに変換できます。
また、SVは内部にプリミティブな型も保持(has-a関係を持つ)しています。そのプリミティブな型を紹介していきます。
IV──符号付き整数の型
IV(Integer Value)は、整数を表す型です。Cのint型へキャストできます。
UV──符号なし整数の型
UV(Unsigned Integer Value)は、符号なしの整数を表す型です。Cのunsigned int型へキャストできます。
NV──倍精度の型
NV(Numeric Value)は、倍精度を表す型です。Cのdouble型へキャストできます。
PV──文字列の型
PV(Pointer Value)は、文字列を表す型です。Cのchar*型へキャストできます。
SVとプリミティブな値
SVからプリミティブな値を取得するには、次のAPIを用います。
プリミティブな値を表すSVを作成したい場合は、次のAPIを用いて変換します。
これらの操作を覚えておくことで、SVからCのintやchar*の作成も容易になります。
<続きの(2)はこちら。>
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
- 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう
- 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、NFT