nDiki : XS
スポンサード リンク
Related term
2004年2月19日 (木)
■ [ Perl ] PDL::PP で C extension を書く

PDLを使ったPerl数値処理プログラムによりインタラクティブ性が求められるようになってきたので、一部をCで書いて高速化する事を検討。 問題は Linux でも Windows + ActivePerl でもすんなり動くかどうか。
@ .pd ファイルを書く
とりあず PDL::PP のサンプルから sumit 関数あたりを MathEx.pd に書いておく。
@ Makefile.PLを修正する
Foo::Bar パッケージの中の Foo::Bar::Math の一部を Foo::Bar::MathEx に移して、C extension 化したい。 ということで lib/Foo/Bar/MathEx.pd として、Makefile.PL の各種設定をしてみる。
がどうもうまくいかない。 PDL::PP の Makefile.PLサポートは、Makefile.PL と同じ位置に .pd がある事を想定しているようなので、いろいろと小細工をしなければならない。 一方 Perl の XS は Foo::Bar のベース名から Bar.so を作る前提になっているようで、これまたパッケージの中の一部のモジュールをどうもXS化しにくい。
@ 子Makefile.PLを作る
Perl の ext/SDBM_File を真似て、子 Makefile.PL を使ってみることにした。
Foo-Bar-x.xx | +- Makefile.PL | +- lib | | | +- Foo | | | +- Bar.pm | | | +- Bar | | | +- Math.pm | | | +- MathNoEx.pm | | | ... | | +- blib/... | +- MathEx | | | +- Makefile.PL | | | +- MathEx.pd ...
パッケージディレクトリの下に MathEx ディレクトリを作り、そこに Makefile.PL と MathEx.pd を置く。 Makefile.PL は MathEx.pd 専用になるので、PDL::PP の標準的なものでOKになる。
全体のパッケージング・PPM化・インストール等が面倒にならないかと心配したが、Foo-Bar パッケージ化で perl Makefile.PL、make xxx を実行すれば子Makefile.PLまできちんと面倒をみてくれる。 MathEx 以下でビルドしたものもパッケージの blib に一緒に入れてくれるし(=一緒にインストールできる・PPM化できる)。 逆に make dist の際には子Makefileの方は余計なとりまとめはしないで、親Makefileが一括して tar.gz に入れてくれる。 これはよい。 MathEx.pd もきちんと Foo/Bar/MathEx.so になった。
@ XSが使えない環境との両対応
XSが使えない環境のために、PerlとPPの両方で関数を書いておく。 XSが使えれば MathEx を、使えなければ MathNoEx.pm を使うように。 表向きのAPIは Foo::Bar::Math とし、ここで AUTOLOAD を使ってどちらか一方を呼び出すようにする。 間接呼び出しにして遅くなるのはいやなので、シンボルテーブルを直接設定する。
use vars qw($IMPLEMENT_CLASS $AUTOLOAD);
BEGIN {
$IMPLEMENT_CLASS = 'Foo::Bar::MathEx';
eval "use $IMPLEMENT_CLASS";
if ($@) {
warn "Can't load $IMPLEMENT_CLASS: $@";
$IMPLEMENT_CLASS = 'Foo::Bar::MathNoEx';
eval "use $IMPLEMENT_CLASS";
die $@ if $@;
}
}
sub AUTOLOAD {
my $name = $AUTOLOAD;
$name =~ s/.*://;
my $implement = $IMPLEMENT_CLASS . '::' .$name;
no strict "refs";
*{$name} = \&{$implement}; # ここでシンボルテーブル設定
return &{$implement}(@_);
}
最初は、AUTOLOAD の最後の行で die したら、trap してエラーメッセージ中のパッケージ名(Foo::Bar::MathEx や Foo::Bar::MathNoEx)を呼び出された Foo::Bar::Math に置換して die し直すようにしようかと思ったが面倒なのでやめ。
@ ActivePerl 5.6 + Visual C++ 6
使っているWindows BOX には Visual C++ 6 が入っているので、XSも問題なくビルドでき PDL extension もうまく動いた。
PPM化までここで済ませば、他のPCにも持っていけるはず。
@ さて
これでバシバシPPで書けるわけだが、PPがこれまた難解で最初は苦労しそう。
- PAR::Repository でビルド済み Perl モジュールをネット... (2006-12-12)
- ActivePerl で Ming (2005-02-23)
- nmake で毎回 pl2bat されるのを何とかしたい (2004-11-25)
- PAR を ActivePerl 5.6.1 build 638 に (2004-07-20)
- 自前 PPM リポジトリの管理 (2006-07-03)
2004年7月20日 (火)
■ PAR を ActivePerl 5.6.1 build 638 に

昨日 Linux 上で実験してみた PAR を Windows にも入れてみる。 PDLを使っている関係で ActivePerl は 5.6.1。
@ インストール
ppm install で入るパッケージは古いので、最新のものを入れておく。 ちょっと手間。
- PAR が必要とする Parse::Binary と Win32::Exe は ppm がないので、自分でとってきて make_ppm。
- PAR 0.85 は 'ppm install PPM::Make' ではいる make_ppm だとパッケージ作成失敗。PPM::Make 0.71 に上げる (古い PPM::Make で ppm 化可能)。
- PPM::Make 0.71 は新しい Getopt::Long を必要とするので、こちらもソースをとってきて ppm 化。
- その他必要なパッケージもインストール (Config::IniFiles)。
ワンライナーを pp できるところまで動作確認。
@ モジュール + スクリプトを実行可能形式に
ExtUtils::Makemakerを使ってパッケージ化している開発中のモジュール(スクリプトあり、XS あり)を実行可能形式化してみる。
perl Makefile.PL nmake nmake test cd blib set PERL5LIB=lib;arch (pp の -I オプションが効かなかったので) pp -o foo.exe -a lib -a arch -M ... -c script/foo
Log::Log4perl::Appender::Screen、Jcode::Unicode::NoXS、Unicode::String、GD については依存関係を自動検出できなかったので、それぞれ -M で指定。
できた。動いた。素晴しい。 PDL や GD を使っていたのでちょっと不安だったのだがうまく動いて感激。 これでCD-ROMとか USB メモリに入れておいて一発実行とかできる。
- [ Perl ] PDL::PP で C extension を書く (2004-02-19)
- PAR::Repository でビルド済み Perl モジュールをネット... (2006-12-12)
- 自前 PPM リポジトリの管理 (2006-07-03)
- PPM::Make と META.yml (2004-10-14)
- ActivePerl で Ming (2005-02-23)
2006年12月12日 (火)
■ PAR::Repository でビルド済み Perl モジュールをネットワーク配信

@ 実行可能ファイル作成としての PAR
PAR といえば Perl スクリプトを実行可能ファイル(Windows なら EXE 形式ファイル)に変換するモジュールとして有名である。
ちなみに実行可能ファイルを作成する部分はは PAR 0.97 より PAR-Packer パッケージに分けられ、PAR 自体はインストールしやすい pure Perl なパッケージになっている。
@ PAR モジュールアーカイブからのローダとしての PAR
PAR が提供するもう一つの(こちらが本来はメイン?)機能は、プログラムの実行時に必要な Perl モジュールを PAR ファイルと呼ばれる Perl モジュールアーカイブファイルからロードする機能である。 XS モジュールなどもコンパイルすることができるどこかの環境で1度ビルドして PAR ファイルにしておけば、同じアーキテクチャのホスト上でそのまま利用することができる。
@ PAR リポジトリ
ロードしたい PAR ファイルはファイルパスだけではなく URL でも指定することができ、必要な時にオンデマンドでフェッチさせることができる。 これを使えば Perl プログラムの集中管理可能だ。
PAR 0.951 からは PAR リポジトリというコンセプトが追加され、パッケージ毎に作った PAR ファイルをサーバ上(あるいはローカル)のリポジトリに蓄積してオンデマンドでロードできるようになった。
個別に PAR ファイルを指定する従来の方式に比べてかなり便利そうである。 ということで試用してみた。
まずは
- PAR
- PAR::Repository
- PAR::Repository::Client
- PAR::Repository::Query
- PAR::Dist
- PAR::Packer
あたりをインストールし準備 OK。
@ 1. PAR リポジトリを作成する
最初に PAR-Repository に含まれている parrepo で。
parrepo create -r /tmp/PAR
PAR リポジトリファイルの中にはデータベースファイルが作成されるが、これは DBM::Deep というアーキテクチャ非依存のものを使っているので、Linux でも Windows でもどちらからでもアクセス可能である (つまり Linux 上でリポジトリをメンテできるということだ)。
@ 2. Perl パッケージを PAR ファイル化する
次に必要な PAR ファイルを作成する。 作成したいパッケージを展開してビルドし、blib ができている状態で PAR::Dist を使ってパッケージ化する。
perl Makefile.PL make make test perl -MPAR::Dist -e blib_to_par
例えば ActivePerl*1 上で WWW-Mechanize-1.20 を PAR ファイル化すると
WWW-Mechanize-1.20-MSWin32-x86-multi-thread-5.8.8.par
というファイルが作成される。
普段から ActivePerl で必要なライブラリは基本的に自前で PPM パッケージ化して、動作確認した上で PPM リポジトリに蓄積するようにしているので、合わせて次の手順でパッケージを作ることになる。
perl Makefile.PL nmake nmake test perl -MPAR::Dist -e blib_to_par make_ppm
@ 3. PAR リポジトリに PAR ファイルを登録する
PAR ファイルができたら parrepo でリポジトリに登録する。
parrepo inject -r /tmp/PAR -f xxx.par
@ 4. PAR リポジトリ上のライブラリを使用してみる
例えば先ほどの WWW::Mechanize がリポジトリに登録されている状態で
#!/usr/bin/perl
use PAR { repository => 'file:///tmp/PAR/' };
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('http://www.example.com');
print $mech->content;
というスクリプトを書いて実行すると、PAR リポジトリから WWW::Mechanize がロードされて正しく実行される。
ここでリポジトリを Web サーバへアップロードして、repository のところに URL を指定するようにすることもできる。 例えばリポジトリを http://www.example.com/PAR/ に配置したとすると
#!/usr/bin/perl
use PAR { repository => 'http://www.example.com/PAR/' };
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('http://www.example.com');
print $mech->content;
と書き換えることで、インストールしていない WWW::Mechanize を使用できるようになる。
@ Perl プログラムを実行形式化する
先ほどの Perl スクリプトを get_top_page.pl という名前で保存して pp で実行可能ファイル化する。
pp -o get_top_page.exe -M PAR::Repository::Client get_top_page.pl
とすれば get_top_page.exe という実行可能ファイルが作成される。 WWW::Mechanize はオンデマンドで http://www.example.com/PAR/ からフェッチされるので、アップデートが必要な場合は新しい PAR ファイルを作成してリポジトリを更新するだけでよい。 EXE ファイルを作成しなおして利用者に配付しなすといった作業も不要だ。
@ スクリプトもリポジトリにおく
さらには実行するスクリプトをも PAR リポジトリに置いておくことが可能だ。
例えば WWW-Mechanize に含まれている mech-dump をオンデマンドにフェッチして実行する実行形式ファイルは以下のコマンドで作成できる。
pp -o mech-dump.exe -M PAR::Repository::Client \
-e "use PAR { repository => 'http://www.example.com/PAR/', \
run => 'mech-dump' }"
@ まとめ
ActivePerl では PPM があるとはいえ、普通のユーザにちょっとしたプログラムを使ってもらうのに「ActivePerl をインストールして、PPM パッケージをインストールして、……」というのは手間すぎる。
pp で プログラムに必要なものを全てバンドルした実行形式化ファイルにするという方法ももちろんあるのだが、頻繁にアップデートするようなスクリプトの場合には、起動のための部分だけ pp で作成しておいてあとは PAR リポジトリで集中管理するというのもちょっと魅力的である。
- 自前 PPM リポジトリの管理 (2006-07-03)
- [ Perl ] PDL::PP で C extension を書く (2004-02-19)
- ActivePerl をやめて Strawberry Perl へ (2009-08-25)
- ActivePerl 5.8.9 build 825 + MinGW 5.... (2009-02-22)
- ActivePerl で Ming (2005-02-23)
2007年4月7日 (土)
■ 携帯電話(iモード)から Twitter を更新する

Twitter をいろいろ遊んでみて「やはり携帯電話から更新できないと」と思えてきた。
携帯電話からメールを送る事で Twitter にアップデートをかけてくれるゲートウェイを設置できれば一番いいのだけれど、そのようなメールアドレスを作る場所が今はない(さすがに会社のサーバはまずい)。
ということでiモードから更新をかけられるように短い CGI プログラムを書くことにした。 CPAN には Net::Twitter という Perl モジュールがあるのだが、JSON::Any (と JSON::XS / JSON / JSON::DWIW / JSON::Syck のどれか)が必要で、ちょっと大げさなので今回は使用は見送り。 普通に CGI.pm と LWP::UserAgent で書いた。
#!/usr/bin/perl -w
use 5.005_03;
use strict;
use CGI qw(-no_xhtml);
use Jcode;
use LWP::UserAgent;
my $query = CGI->new;
my $user_name = $query->param('u');
my $password = $query->param('p');
my $status = $query->param('s');
$user_name = '' unless defined $user_name;
$password = '' unless defined $password;
$status = '' unless defined $status;
my $message = '';
if ($user_name ne '' && $password ne '' && $status ne '') {
my $ua = LWP::UserAgent->new;
Jcode::convert(\$status, 'utf8', 'sjis');
$ua->credentials('twitter.com:80', 'Twitter API', $user_name, $password);
my $request = $ua->post('http://twitter.com/statuses/update.json',
{status => $status . ' '});
if ($request->is_success) {
$message = '<p>OK</p>';
}
}
print $query->header(-type => 'text/html', -charset => '');
print '<html><head><title>Twitter update</title></title><body>';
print '<form method="post" action="twitter">';
print 'ユーザ名:', $query->textfield('u'), '<br>';
print 'パスワード:', $query->password_field('p'), '<br>';
print 'ステータス:', $query->textfield('s'), '<br>';
print '<input type="submit">';
print '</form>';
print $message;
print '</body></html>';
とりあえずこれで、iモードから送信できることを確認。 パスワードの入力が面倒だけれども、サーバ側に書いておくのも嫌なので毎回送ることにした。FOMA 端末側には定型文として保存しておく以外にいい手はないのかな。
最初うまく送れなくてなんだろうと思ったが、あきやん氏の「Twitterで日本語を入力する方法 (akiyan.com)」の記事にある
- 全て全角文字で入力して、最後に半角スペースをいれる
- 半角全角を混在させるときは、半角文字と全角文字の間にスペースをいれる
といった日本語を入力する際の注意点がらみだったようである。 とりあえず CGI プログラムの方で最後に必ずいわゆる半角空白を追加するようにしておいた。
文字数チェックとか Twitter API の返り値チェックとか、改善すべきところはいろいろあるけれど、自分用にはまずこれでいいかな。
気が向いた時に外出先から更新かけます。
- 携帯電話からの Twitter 投稿に tmitter を使ってみることにした (2007-07-26)
- Plagger で Twitter のあれこれをメールで通知 (2008-12-25)
- 今日のさえずり - くるぴかポッチャマ廻しにくい (2009-12-27)
- ケータイ用にプライベート Wiki を設置 (2008-01-07)
- MAILPIA による Twitter リプライチェック (2008-11-18)
2009年8月19日 (水)
■ 今日のさえずり - 選挙カー vs 廃品回収車

@ 2009年08月17日
- 12:10 限界がきて穴の開いたパンツや靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3
- 12:50 今のところ洗濯派2、そのまま捨てる派2。 RT @Naney: 限界がきて穴の開いたパンツや靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3 *P3
- 14:07 zakwa がいなくなって以来、久しぶりの社内コーヒーサービス(賞味期限今日まで)。 *P3
- 14:29 Text::CSV_XS::Encoded 一所懸命探してた。 Text::CSV::Encoded だった。 *P3
- 16:53 今のところ洗濯派4、そのまま捨てる派4。拮抗している。 RT @Naney: 限界がきて穴の開いたパンツや靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3 *P3
- 17:08 歯医者につき退社。 [mb]
- 17:10 後ろの人に「今帰ったら日焼けするよ」と脅された。 [mb]
- 18:19 歯医者へ GO。 [mb]
- 19:07 今日の歯医者終了。インレー詰めて痛む奥歯でしばらく強く噛み続けるプレイを味わった。 [mb]
@ 2009年08月18日
- 09:09 昨日の朝から背中が痒い。原因不明なのでムヒ塗っておく、ムヒ。 [mb]
- 09:35 東京国際フォーラムのシャッターの向こうにワサワサ人がいた。あれなんだろ。 [mb]
- 09:45 調査員がホームレスにインタビューしてる。 #Akihabara L:秋葉原駅 [mb]
- 12:19 会社の女の子がお台場ガンダムについて熱く語っている。 *P3
- 12:41 2009年8月17日の歩行: 7037歩、5.42km、61分、5.30km/h、消費 269.0kcal、脂肪燃焼 38.4g、3.9エクササイズ。 *P3
- 12:49 滞在時間何時間? RT @naofumiyoshida: Naha, Okinawa. / 日帰り出張で那覇到着。 *P3
- 12:54 敷布団って結局どちらを上にして寝れば良いのだろう。房のある方が上? 下? *P3
- 12:59 選挙カー vs 廃品回収車。 *P3
- 20:06 @naofumiyoshida 沖縄滞在8時間半ですか。結構居られるんですね。日帰りなんて芸能人みたい。 [mb]
@ 2009年08月19日
- 12:28 2009年8月17日の歩行: 7037歩、5.42km、61分、5.30km/h、消費 269.0kcal、脂肪燃焼 38.4g、3.9エクササイズ。 *P3
- 12:29 2009年8月18日の歩行: 4798歩、3.68km、41分、5.30km/h、消費 184.5kcal、脂肪燃焼 26.4g、2.7エクササイズ。 *P3
- 12:32 今日から花輪ばやし。 http://tinyurl.com/lcr4el *P3
- 12:36 最近のカメラ屋は。 RT @fujiyacamera: フジヤカメラ店 )))))))♡ 愛と勇気をただいまお届け致しました *P3
- 14:26 ThinkPad X31 が Caps Lock ランプ点滅させてハングったので再起動したところ (Debian GNU/Linux sid)。 *P3
- 16:45 「ほぼ日乗組員が紹介する、ほぼ日手帳2010」観た(音無し)。酔う映像でちょっとつらかった。 *P3
- 20:16 久しぶりに京浜東北線内でコーディング。 [mb]
- 今日のさえずり - 「深呼吸してください。」が無くなったのは残念 (2009-09-24)
- 今日のさえずり - ピカチュウと写真撮ってもらえる列に並んでる (2009-11-24)
- 今日のさえずり - フロスティ食べたい (2009-12-10)
- 今日のさえずり - 夏が終わったのに黄色かよ (2009-10-02)
- 今日のさえずり - 右から左に線を書くと、左利きになった気分が味わえる (2009-09-30)
■注目キーワード
購入 買った 発売日 フリー 無料 価格 値段 作り方 選び方 使い方 方法 設定 サンプル ダウンロード 限定 在庫 予約 穴場 比較 検証 レビュー 感想 評価 評判 使用感 使ってみた 口コミ 噂 最新 MP3 動画 意味 お薦め お勧め おすすめ 便利 Blog ブログ mixi 修理 デザイン ビックカメラProcess Time: 0.077689s / load averages: 0.14, 0.12, 0.09
nDiki by WATANABE Yoshimasa (profile)
Powered by DiKicker
Base theme by Nana (for tDiary)




■ Twitter やってます。この記事が気にいったらぜひ twitter.com/Naney の follower になってください。
■ Google Buzz はよろしければ Naney の Google プロフィールからどうぞ。