Yapcasia2011 - Hello Embed Perl
Upcoming SlideShare
Loading in...5
×
 

Yapcasia2011 - Hello Embed Perl

on

  • 2,956 views

 

Statistics

Views

Total Views
2,956
Views on SlideShare
2,418
Embed Views
538

Actions

Likes
0
Downloads
11
Comments
0

5 Embeds 538

http://d.hatena.ne.jp 481
http://yapcasia.org 52
http://www.slideshare.net 3
http://a0.twimg.com 1
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • まず、自己紹介からさせてください。\nはじめまして大野秀明と言います。\nYAPC::Asiaに参加するのは今回が2回目です。\nそもそもPerlのコミュニティに関わったのが去年のYAPC::Asiaが初めてで、その後この一年Hachioji.pm、Perl Advent Calendarに参加するなど関わってきました。\n普段の仕事は所謂SIerでスーツ着て仕事をしています。\n\n
  • \n
  • \n
  • \n
  • \n
  • ・CプログラムにPerlインタプリタを追加する\n・PerlサブルーチンをCプログラムから呼び出す\n・CプログラムからPerlの文を評価する\n・CプログラムからPerlのパターンマッチ、置換を実行する\n・CプログラムからPerlのスタックを操作する\n
  • このようにCプログラムからPerlインタプリタにPerlコードを送り込みその出力を得るという形式になります\n
  • 埋め込みPerlを利用したプログラムで有名なものをあげています。\nmod_perlはApache HTTP ServerにPerlインタプリタを埋め込むというもの\nnode-perlを作った動機はただ作りたかったから\nNode.jsで何か作りたい、Node.js のアドオンはC++で書ける、C++ということはCのライブラリも使える、PerlインタプリタはCだから組み込める!という極めて自然な流れです。\n
  • \n
  • ・Perlといえば正規表現、正規表現といえばPerlと言ってもいいくらい切っても切れない関係\n・夏のShibuya.pmもテーマは正規表現、正規↑表現↓?\n・Perlを正規表現エンジンとして使えば、PCREとか使わなくても100%Perlコンパチブルな正規表現が使える\n
  • ・柔軟かつ強力な文字列操作\n・CPANの力の恩恵を受けることができる\n
  • 組み込みPerlインタプリタの基礎\n
  • \n
  • これが最も単純な埋め込みPerlインタプリタの例です。\nこれは通常のperlと同様に引数としてファイル名が渡されれば実行し、-eオプションなどの実行もできます\n
  • EXTERN.hはWindowsなど特定のOS用のシンボルを定義します\nperl.hはコンパイルオプションに従ってシンボルを定義したり、ヘッダファイルをインクルードする\n
  • C++から使う場合はextern “C” を使用\n
  • ・perl_alloc()はメモリの確保\n・perl_constract()がインスタンスの初期化\n・複数のインタプリタを使用する場合は、PERL_SET_CONTEXT()というマクロを使用する必要がある\nこれは、現在のインタプリタを特定するためのグローバルな状態を初期化するためのもので、実際にはcthread_set_data()でスレッドローカルストレージにインタプリタの情報を保存する\n
  • ・get_hash_seed() ハッシュテーブルのためのシードを取得\n・parse_body()ではyyparse()で構文解析、yylex()で字句解析、OPCODEツリー構築、PL_checkによる文法エラーチェック、OPCODEツリーの変換、最適化を行われる\n・process_special_block()でBEGINブロック実行、UNITCHECK、CHECK、ENDは配列にunshift、INITはpushされていく\n\n
  • これがperl_parseのプロトタイプです。\nここで注目すべきは第二引数のxsinitです。\nこのxsinitはC/C++で書かれたモジュールをロードする関数への関数ポインタです。\nこのxsinitでDynaloaderやXSLoader、独自のブートストラップが必要なモジュールがあればそのブートストラップを呼び出します。\nこのxsinitはExtUtils::Embedで生成できるのでリンクすれば問題ありません\n
  • perl_run()の動作としては\n・INITブロックの実行\n・Perlコードの実行\n・mod_perlの場合は初期化時に1回だけ実行されます。このあたりがmod_perlと遅延ロードやAttributeと相性が悪い原因\n・nginxのperl moduleはperl_run()は実行しません\n
  • \n
  • \n
  • 問:Cプログラムから結果を取得するにはどうすればいいのでしょうか?\n
  • A:やり方は一つじゃない\n
  • こちらが一般的な方法\nmod_perlもnginxのperl moduleもこの方法\n特定の変数に結果を収める必要があるため、自由度が低い\n・XPUSHs()で引数となる変数をスタックに積んで、call_sv()でサブルーチンが実行される。\n・countは戻り値の数\n・POPsでスタックから引数を取り出す\n
  • 標準出力、標準エラー出力の出力先をスカラ変数に変える\n
  • \n
  • Perl_do_open9()でハンドルの出力先としてスカラ変数のリファレンスを指定している\n
  • 保存しておいた元のファイルハンドルを取り出して、復帰させる\n
  • やってることはコレと似たようなもの\n
  • コンパイルについてはExtUtils::Embedを利用すれば必要なコンパイルオプションを生成してくれます。\n埋め込みPerlをコンパイルする他の方法を知りたい場合はperldoc perlembedを見てください\n
  • \n
  • 埋め込みPerlをやるにあたって、必要な情報源です。\nperlembedは必読としてあとはXS関連のperldocを読みましょう。\n書籍では少し古くて、洋書ですがExtending and Embedding Perlという本があります。PDF版であれば$36程度で買えるはずです。\n
  • ・埋め込みPerlは難しくありません\n・もしあなたのCプログラムでPerlの力が必要になったら迷わず埋め込みPerlの正解に飛び込みましょう\n・また、埋め込みPerlに挑戦することにより、Perlに対する理解がさらに深まります\n
  • ご清聴ありがとうございました。\n何か質問はありますでしょうか?\n

Yapcasia2011 - Hello Embed Perl Yapcasia2011 - Hello Embed Perl Presentation Transcript

  • Hello Embed Perl! Hideaki Ohno YAPC::Asia Tokyo 2011
  • About meHideaki Ohno Github: hideo55 Twitter: @hide_o_55 PAUSE: HIDEAKIO Blog: http://d.hatena.ne.jp/hide_o_55/ Perl/C/C++/JavaScript
  • AgendaWhat’s embed perl?Why use embed perlCommon sense of embed perl
  • Hello embed perl!
  • embed perl?
  • What’s embed perl?
  • What’s embed perl?Using Perl From C Adding a Perl interpreter to C program Calling a Perl subroutine from C program Evaluting a Perl statement from C program Performing Perl pattern matches and substitutions from C program Fidding with the Perl stack from C program
  • Adding a Perlinterpreter to C program
  • Example of embed perl mod_perl (Apache) http_perl_module (Nginx) PL/Perl (PostgreSQL) MyPerl (MySQL)
  • Example of embed perl mod_perl (Apache) http_perl_module (Nginx) PL/Perl (PostgreSQL) MyPerl (MySQL) node-perl (Node.js)
  • Why use embed perl?(What are merits of embed perl)
  • Why use embed perl? Regexp!!!
  • Why use embed perl? Regexp!!!Don’t needs PCRE because perl’s regexp engineis 100% perl compatible!
  • Why use embed perl? CPAN!!!
  • Common sense of embed perl
  • Perl data typeSV SCALAr valueAV ARRAY valueHV HASH valueGV Glob valueRV Reference value
  • Basic usage#include <EXTERN.h>#include <perl.h>static PerlInterpreter *my_perl;int main(int argc, char **argv, char **env){ PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(my_perl, NULL, argc, argv, (char **)NULL); perl_run(my_perl); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}
  • Include#include<EXTERN.h>Define symbols for specific OSssuch as Windows.#include<perl.h>Define symbols and include headerfiles in accordance with compileoptions
  • IncludeFrom C++extern “C” {#include<EXTERN.h>#include<perl.h>}
  • Create interpreterPerlInterpreter *perl = perl_alloc();perl_construct(perl);If you want use multiple interpreter,use PERL_SET_CONTEXT().It initialize global state for trace“current” interpreter.
  • Parseperl_perse()This function parse and compile perl code.
  • Parseperl_parse( register PerlInterpreter *my_perl, XSINIT_t xsinit, int argc, char** argv, char** env);xsinit is function pointer of initializeXS module.perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c
  • Runperl_run() Execute “INIT” Block Execute perl code mod_perl execute this function once at initialize time. nginx perl module don’t execute this function.
  • Why nginx don’t execute perl_run()?PL_exit_flags |= PERL_EXIT_DESTRUCT_END;If set PL_exit_flagsPERL_EXIT_DESTRUCT_END, “END” Block isexecuted in perl_destruct().
  • Destructorperl_destruct() Execute “END” block. Objects destructionperl_free() Free allocated memory
  • Q. How to get result from C program?
  • A. TIMTOWDI
  • Call subroutine and get return valuedSP;ENTER;SAVETMPS;PUSHMARK(sp);XPUSHs(...); //push some variables to stackPUTBACK;count = call_sv(sub, G_EVAL);SPAGAIN;if (count != 1) croak(“”);x = SvPVx(POPs, n_a);
  • Override PerlIO layersChanging the destination for STDOUT/STDERRto scalar variables.
  • Override PerlIO layers extern "C" { #define PERLIO_NOT_STDIO 0 #define USE_PERLIO #include <EXTERN.h> #include <perl.h> } See also perlio.h
  • Override PerlIO layersvoid override_stdhandle (pTHX_ SV *sv,const char *name ) { int status; GV *handle = gv_fetchpv(name,TRUE,SVt_PVIO); SV *svref = newRV_inc(sv); save_gp(handle, 1); status = Perl_do_open9(aTHX_ handle, ">:scalar", 8 , FALSE, O_WRONLY, 0, Nullfp, svref, 1); if(status == 0) { Perl_croak(aTHX_ "Failed to open %s: %" SVf,name, get_sv("!",TRUE)); }}
  • Override PerlIO layersvoid restore_stdhandle (pTHX_ const char *name) { int status; GV *handle = gv_fetchpv(name,FALSE,SVt_PVIO); if( GvIOn(handle) && IoOFP(GvIOn(handle)) &&(PerlIO_flush(IoOFP(GvIOn(handle))) == -1 ) ) { Perl_croak(aTHX_ "Failed to flush %s: " SVf,name,get_sv("!",TRUE) ); }}
  • Override PerlIO layers{ local *STDOUT; my $stdout; open STDOUT, ‘>’, ¥$stdout or die $!; ...}
  • Compileuse ExtUtils::Embed% cc -o myperl myperl.c `perl -MExtUtils::Embed-e ccopts -e ldopts`See ‘perldoc perlembed’ if you want to knowother way of to compile embed perl.
  • Otherseval eval_pv() eval_sv()
  • Referenceperldoc perlembedperldoc perlcallperldoc perlapiperldoc perlxsperldoc perlgutsperldoc perlapioBook - Extending and Embedding Perl
  • SummaryEmbed perl is not difficultIf you need the power of Perl in your Cprogram, then hesitate to jump into theworld of embedded PerlBy challenging the embedded Perl, evendeeper understanding of Perl
  • Thanks for your attention.