C++のライブラリをXSから利用する方法
PerlのXSではC++で書かれたライブラリを呼び出すこともできます。コンパイラとリンカに、C++用の「g++」を指定するだけです。
h2xsでモジュールを作成
最初にh2xsでXS用のモジュールを作成します。
h2xs -A -n SomeModule
こうすると「SomeModule」というディレクトリが作成されます。次のようなファイルとディレクトリが作成されます。
Changes lib/ Makefile.PL MANIFEST ppport.h README SomeModule.xs t/
C++のライブラリの作成
C++のライブラリを作成しましょう。ヘッダファイルとソースファイルを作成します。
mylib.h
ヘッダファイルです。mylib_printを宣言しています。
void mylib_print();
mylib.cpp
C++のソースファイルです。mylib_printは「mylib_cpp」という文字列を出力する関数です。ファイル名の拡張子が「.cpp」であることに注意してください。
#include <iostream> void mylib_print() { std::cout << "mylib_cpp\n"; }
ヘッダファイルとソースファイルは保存して、XSファイルが存在するディレクトリと同じディレクトリに配置してください。
XSファイルの記述
XSファイルを記述しましょう。mylib_printを呼び出しています。
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include "mylib.h" MODULE = SomeModule PACKAGE = SomeModule void foo(...) PPCODE: { mylib_print(); XSRETURN(0); }
Makefile.PLの修正
次にMakefile.PLを少し修正しましょう。一番下の「OBJECT」オプションがデフォルトではコメントアウトされているので、コメントを取り除きます。「$(O_FILES)」という設定をすれば、カレントディレクトリのすべてのC言語のソースファイルとC++のソースファイルがコンパイルの対象になります。
そしてコンパイラとリンカを「g++」に変更します。コンパイラは「CC」オプション、リンカは「LD」で設定できます。
use ExtUtils::MakeMaker; use strict; use warnings; WriteMakefile( NAME => 'SomeModule', VERSION_FROM => 'lib/SomeModule.pm', # finds $VERSION PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/SomeModule.pm', # retrieve abstract from module AUTHOR => 'A. U. Thor <kimoto@sakura.ne.jp>') : ()), LIBS => [''], # e.g., '-lm' DEFINE => '', # e.g., '-DHAVE_SOMETHING' INC => '-I.', # e.g., '-I. -I/usr/include/other' OBJECT => '$(O_FILES)', # link all the C files too CC =>'g++', LD => 'g++', );
テストスクリプト
テストスクリプトを作成します。これは、XSファイルがあるディレクトリと同じディレクトリにおいてください。
use strict; use warnings; use SomeModule; SomeModule::foo();
コンパイルして実行
コンパイルして実行してみましょう。
perl Makefile.PL make perl -Mblib test.pl
次のように出力されれば成功です。
mylib_cpp
これで、C++のライブラリをXSファイルから利用することができるようになりました。
FAQ
XSファイルの中に直接C++を記述することはできますか。
できます。けれども、Perlのシンボルと衝突してしまうなどの不具合が起こりがちですので、ソースファイルとヘッダファイルに記述するのがよいと思います。
C言語のライブラリとC++のライブラリを混在させて利用することはできますか。
C++はC言語のほぼ上位互換なので、C言語のライブラリがg++でコンパイル可能であれば大丈夫だと思います。そうでない場合は、ちょっとわかりません。