argra****@users*****
argra****@users*****
2017年 3月 20日 (月) 20:41:07 JST
Index: docs/perl/5.22.1/perlembed.pod diff -u /dev/null docs/perl/5.22.1/perlembed.pod:1.1 --- /dev/null Mon Mar 20 20:41:07 2017 +++ docs/perl/5.22.1/perlembed.pod Mon Mar 20 20:41:07 2017 @@ -0,0 +1,2112 @@ + +=encoding euc-jp + +=head1 NAME + +=begin original + +perlembed - how to embed perl in your C program + +=end original + +perlembed - C プログラムへの Perl の埋め込み方 + +=head1 DESCRIPTION + +=head2 PREAMBLE + +=begin original + +Do you want to: + +=end original + +あなたのやりたいことは + +=over 5 + +=item B<Use C from Perl?> + +(B<Perl から C を使うことですか?>) + +=begin original + +Read L<perlxstut>, L<perlxs>, L<h2xs>, L<perlguts>, and L<perlapi>. + +=end original + +L<perlxstut>, L<perlxs>, L<h2xs>, L<perlguts>, L<perlapi> を +読みましょう。 + +=item B<Use a Unix program from Perl?> + +(B<Perl から UNIX プログラムを使うことですか?>) + +=begin original + +Read about back-quotes and about C<system> and C<exec> in L<perlfunc>. + +=end original + +バッククォートに関することと、 +L<perlfunc>にあるC<system>、C<exec>に関することを読みましょう。 + +=item B<Use Perl from Perl?> + +(B<Perl から Perl を使うことですか?>) + +=begin original + +Read about L<perlfunc/do> and L<perlfunc/eval> and L<perlfunc/require> +and L<perlfunc/use>. + +=end original + +L<perlfunc/do>、 L<perlfunc/eval>、L<perlfunc/require>、 +L<perlfunc/use>を読みましょう。 + +=item B<Use C from C?> + +(B<C から C を使うことですか?>) + +=begin original + +Rethink your design. + +=end original + +デザインを考え直しましょう。 + +=item B<Use Perl from C?> + +(B<C から Perl を使うことですか?>) + +=begin original + +Read on... + +=end original + +読み続けてください… + +=back + +=head2 ROADMAP + +(ロードマップ) + +=over 5 + +=item * + +=begin original + +Compiling your C program + +=end original + +C プログラムをコンパイルする + +=item * + +=begin original + +Adding a Perl interpreter to your C program + +=end original + +C プログラムに Perl インタプリタを追加する + +=item * + +=begin original + +Calling a Perl subroutine from your C program + +=end original + +C プログラムから Perl サブルーチンを呼び出す + +=item * + +=begin original + +Evaluating a Perl statement from your C program + +=end original + +C プログラムから Perl の文を評価する + +=item * + +=begin original + +Performing Perl pattern matches and substitutions from your C program + +=end original + +C プログラムから Perl のパターンマッチングや置換を実行する + +=item * + +=begin original + +Fiddling with the Perl stack from your C program + +=end original + +C プログラムから Perl のスタックを扱う + +=item * + +=begin original + +Maintaining a persistent interpreter + +=end original + +永続的(persistent)インタプリタを取り扱う + +=item * + +=begin original + +Maintaining multiple interpreter instances + +=end original + +複数のインタプリタのインスタンスを取り扱う + +=item * + +=begin original + +Using Perl modules, which themselves use C libraries, from your C program + +=end original + +C ライブラリを使っている Perl のモジュールを C プログラムから使う + +=item * + +=begin original + +Embedding Perl under Win32 + +=end original + +Win32 における組み込み Perl + +=back + +=head2 Compiling your C program + +(あなたのCプログラムをコンパイルする) + +=begin original + +If you have trouble compiling the scripts in this documentation, +you're not alone. The cardinal rule: COMPILE THE PROGRAMS IN EXACTLY +THE SAME WAY THAT YOUR PERL WAS COMPILED. (Sorry for yelling.) + +=end original + +このドキュメントにあるスクリプトのコンパイルがうまく行かなくても、 +あなたは孤独ではありません。 +基本的なルールはこうです: +B<あなたが Perl をコンパイルしたときと全く同じやり方でプログラムを +コンパイルしなさい>。 +(叫んでしまってすみません。) + +=begin original + +Also, every C program that uses Perl must link in the I<perl library>. +What's that, you ask? Perl is itself written in C; the perl library +is the collection of compiled C programs that were used to create your +perl executable (I</usr/bin/perl> or equivalent). (Corollary: you +can't use Perl from your C program unless Perl has been compiled on +your machine, or installed properly--that's why you shouldn't blithely +copy Perl executables from machine to machine without also copying the +I<lib> directory.) + +=end original + +また、Perlを使うすべての C プログラムは I<perl ライブラリ> にリンクして +いなければなりません。 +それって何、と聞きますか? +Perl それ自身が C で書かれています。 +Perl ライブラリはあなたの perl 実行ファイル(I</usr/bin/perl> か +これに等価な)を作るために使われたコンパイル済みの C プログラムの +集合体です(あなたの使うマシンで Perl がコンパイルされているか、正しく +インストールされていなければ C プログラムから Perl を使うことはできません。 +これが、Perl の実行ファイルをあるマシンからマシンへ I<lib> ディレクトリ +抜きでコピーしてしまうような軽率なことをすべきでないという理由です)。 + +=begin original + +When you use Perl from C, your C program will--usually--allocate, +"run", and deallocate a I<PerlInterpreter> object, which is defined by +the perl library. + +=end original + +Perl を C から使うとき、その C プログラムは -- 普通は -- perl ライブラリで +定義されている I<PerlInterpreter> オブジェクトの割り付け、「実行」、解放を +行います。 + +=begin original + +If your copy of Perl is recent enough to contain this documentation +(version 5.002 or later), then the perl library (and I<EXTERN.h> and +I<perl.h>, which you'll also need) will reside in a directory +that looks like this: + +=end original + +あなたの使っている Perl がこのドキュメントの内容にあっている(バージョン +5.002 以降)であるのであれば、perl ライブラリ(とこれも必要な +I<EXTERN.H> と I<perl.h>)が次のようなディレクトリに +置かれていることでしょう。 + + /usr/local/lib/perl5/your_architecture_here/CORE + +=begin original + +or perhaps just + +=end original + +あるいは以下のような場所かもしれませんし + + /usr/local/lib/perl5/CORE + +=begin original + +or maybe something like + +=end original + +こうかもしれません + + /usr/opt/perl5/CORE + +=begin original + +Execute this statement for a hint about where to find CORE: + +=end original + +CORE の場所を見つけ出すために以下のような文を実行します。 + + perl -MConfig -e 'print $Config{archlib}' + +=begin original + +Here's how you'd compile the example in the next section, +L<Adding a Perl interpreter to your C program>, on my Linux box: + +=end original + +次のセクション L<Adding a Perl interpreter to your C program> に +ある例をコンパイルするこうします(私のLinux boxでの場合) + + % gcc -O2 -Dbool=char -DHAS_BOOL -I/usr/local/include + -I/usr/local/lib/perl5/i586-linux/5.003/CORE + -L/usr/local/lib/perl5/i586-linux/5.003/CORE + -o interp interp.c -lperl -lm + +=begin original + +(That's all one line.) On my DEC Alpha running old 5.003_05, the +incantation is a bit different: + +=end original + +(これは実際には一行です。) +私の使う DEC Alpha 上で古い 5.003_05 を使う場合では、オマジナイはちょっと +違います: + + % cc -O2 -Olimit 2900 -DSTANDARD_C -I/usr/local/include + -I/usr/local/lib/perl5/alpha-dec_osf/5.00305/CORE + -L/usr/local/lib/perl5/alpha-dec_osf/5.00305/CORE -L/usr/local/lib + -D__LANGUAGE_C__ -D_NO_PROTO -o interp interp.c -lperl -lm + +=begin original + +How can you figure out what to add? Assuming your Perl is post-5.001, +execute a C<perl -V> command and pay special attention to the "cc" and +"ccflags" information. + +=end original + +追加するのものを見つけるにはどうすればよいでしょうか? +あなたの使う Perl が 5.001 より後のものであれば、C<perl -V> を実行して、 +"cc" と "ccflags" の情報に特に注意して見ましょう。 + +=begin original + +You'll have to choose the appropriate compiler (I<cc>, I<gcc>, et al.) for +your machine: C<perl -MConfig -e 'print $Config{cc}'> will tell you what +to use. + +=end original + +あなたは、あなたの使うマシンのために適切なコンパイラ(I<cc>, +I<gcc> など)を選ぶ必要があります。 +C<perl -MConfig -e 'print $Config{cc}'> はあなたに使うべき +コンパイラを教えてくれるでしょう。 + +=begin original + +You'll also have to choose the appropriate library directory +(I</usr/local/lib/...>) for your machine. If your compiler complains +that certain functions are undefined, or that it can't locate +I<-lperl>, then you need to change the path following the C<-L>. If it +complains that it can't find I<EXTERN.h> and I<perl.h>, you need to +change the path following the C<-I>. + +=end original + +同様に、適切なライブラリディレクトリ(I</usr/local/lib/...>) も +選択せねばなりません。 +もしあなたの使うコンパイラが幾つかの関数が +未定義であるとか、I<-lperl> が見つからないという報告をしてきたら、 +C<-L> の後に続くパスを変更する必要があります。 +I<EXTERN.h> や I<perl.h> が見つからないというエラーであれば、 +C<-I> の後にあるパスを変更する必要があります。 + +=begin original + +You may have to add extra libraries as well. Which ones? +Perhaps those printed by + +=end original + +おそらく、さらにライブラリを追加指定する必要があるでしょう。 +どれを? +おそらく以下のようにすれば表示されます: + + perl -MConfig -e 'print $Config{libs}' + +=begin original + +Provided your perl binary was properly configured and installed the +B<ExtUtils::Embed> module will determine all of this information for +you: + +=end original + +あなたの使っている perl のバイナリが適切なコンフィギュレーションが +行われているもので、かつ B<ExtUtils::Embed> モジュールが +インストールされていれば、これによって必要な全ての情報が決定できます。 + + % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + +=begin original + +If the B<ExtUtils::Embed> module isn't part of your Perl distribution, +you can retrieve it from +http://www.perl.com/perl/CPAN/modules/by-module/ExtUtils/ +(If this documentation came from your Perl distribution, then you're +running 5.004 or better and you already have it.) + +=end original + +B<ExtUtils::Embed> モジュールは Perl 配布パッケージに含まれていなければ、 +http://www.perl.com/perl/CPAN/modules/by-module/ExtUtils/ から +入手できます(もしこのドキュメントがあなたの持っている +Perl 配布パッケージにあったものならば、あなたは 5.004 以降のものを +使っているはずで、すでにそのモジュールを持っているはずです。) + +=begin original + +The B<ExtUtils::Embed> kit on CPAN also contains all source code for +the examples in this document, tests, additional examples and other +information you may find useful. + +=end original + +CPAN にある B<ExtUtils::Embed> キットにもこのドキュメントにある例の +すべてのソースコードがあり、テストと追加された例、その他の情報が +あります。 + +=head2 Adding a Perl interpreter to your C program + +(あなたの C プログラムに Perl インタプリタを追加する) + +=begin original + +In a sense, perl (the C program) is a good example of embedding Perl +(the language), so I'll demonstrate embedding with I<miniperlmain.c>, +included in the source distribution. Here's a bastardized, non-portable +version of I<miniperlmain.c> containing the essentials of embedding: + +=end original + +ある意味で、perl(C プログラムとしての perl)は組み込み Perl(言語としての +Perl)の良い例です; ですから、ソース配布にある I<miniperlmain.c> を +使って組込みのデモンストレーションをします。 +以下に示すのは、組込みの本質を持っていて配布ソースにも含まれている +(そして粗悪で移植性に欠ける)I<miniperlmain.c> です。 + + #include <EXTERN.h> /* from the Perl distribution */ + #include <perl.h> /* from the Perl distribution */ + + static PerlInterpreter *my_perl; /*** The Perl interpreter ***/ + + 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(); + } + +=begin original + +Notice that we don't use the C<env> pointer. Normally handed to +C<perl_parse> as its final argument, C<env> here is replaced by +C<NULL>, which means that the current environment will be used. + +=end original + +ここで、C<env> ポインタを使っていないことに注意してください。 +通常は C<perl_parse> はその最終引数として C<env> を取りますが、 +ここではカレントの環境をそのまま使うことを示す +C<NULL> に置き換えられています。 + +=begin original + +The macros PERL_SYS_INIT3() and PERL_SYS_TERM() provide system-specific +tune up of the C runtime environment necessary to run Perl interpreters; +they should only be called once regardless of how many interpreters you +create or destroy. Call PERL_SYS_INIT3() before you create your first +interpreter, and PERL_SYS_TERM() after you free your last interpreter. + +=end original + +PERL_SYS_INIT3() と PERL_SYS_TERM() のマクロは、Perl インタプリタを +実行するのに必要な C ランタイム環境の、システム固有の調整を提供します; +これらはインタプリタが何回作成または破壊されたかに関わらず、1 回だけ +呼び出されるべきです。 +最初のインタプリタを作る前に PERL_SYS_INIT3() を呼び出し、 +最後のインタプリタを解放した後に PERL_SYS_TERM() を呼び出します。 + +=begin original + +Since PERL_SYS_INIT3() may change C<env>, it may be more appropriate to +provide C<env> as an argument to perl_parse(). + +=end original + +PERL_SYS_INIT3() は C<env> を変更するかもしれないので、perl_parse() の +引数として C<env> を提供する方がより適切です。 + +=begin original + +Also notice that no matter what arguments you pass to perl_parse(), +PERL_SYS_INIT3() must be invoked on the C main() argc, argv and env and +only once. + +=end original + +また、どんな引数を perl_parse() に渡したかに関わらず、PERL_SYS_INIT3() は +C main() argc, argv, env から一度だけ起動されなければなりません。 + +=begin original + +Now compile this program (I'll call it I<interp.c>) into an executable: + +=end original + +ここでこのプログラム(I<interp.c> と呼びましょう)をコンパイルして +実行ファイルを作りましょう。 + + % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + +=begin original + +After a successful compilation, you'll be able to use I<interp> just +like perl itself: + +=end original + +コンパイルに成功すれば、perl そのものと同じように +I<interp> を使うことができるでしょう。 + + % interp + print "Pretty Good Perl \n"; + print "10890 - 9801 is ", 10890 - 9801; + <CTRL-D> + Pretty Good Perl + 10890 - 9801 is 1089 + +=begin original + +or + +=end original + +または + + % interp -e 'printf("%x", 3735928559)' + deadbeef + +=begin original + +You can also read and execute Perl statements from a file while in the +midst of your C program, by placing the filename in I<argv[1]> before +calling I<perl_run>. + +=end original + +I<perl_run> を呼び出す前に I<argv[1]> にファイル名を置くことで、 +C プログラムの中ほどで Perl 文をファイルから読み込んで実行するという +こともできます。 + +=head2 Calling a Perl subroutine from your C program + +(あなたの C プログラムから Perl のサブルーチンを呼ぶ) + +=begin original + +To call individual Perl subroutines, you can use any of the B<call_*> +functions documented in L<perlcall>. +In this example we'll use C<call_argv>. + +=end original + +独立した Perl サブルーチンを呼び出すために、L<perlcall> に記載されている +B<call_*> の類の関数を使うことができます。 +次の例では C<call_argv> を使います。 + +=begin original + +That's shown below, in a program I'll call I<showtime.c>. + +=end original + +以下に示すのは、I<showtime.c> という名前のプログラムです。 + + #include <EXTERN.h> + #include <perl.h> + + static PerlInterpreter *my_perl; + + int main(int argc, char **argv, char **env) + { + char *args[] = { NULL }; + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct(my_perl); + + perl_parse(my_perl, NULL, argc, argv, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + + /*** skipping perl_run() ***/ + + call_argv("showtime", G_DISCARD | G_NOARGS, args); + + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + } + +=begin original + +where I<showtime> is a Perl subroutine that takes no arguments (that's the +I<G_NOARGS>) and for which I'll ignore the return value (that's the +I<G_DISCARD>). Those flags, and others, are discussed in L<perlcall>. + +=end original + +I<showtime> は引数をとらない Perl サブルーチン(I<G_NOARGS>)で、その +戻り値を無視します(I<G_DISCARD>)。 +これらのフラグ等は L<perlcall> に説明されています。 + +=begin original + +I'll define the I<showtime> subroutine in a file called I<showtime.pl>: + +=end original + +I<showtime.pl> と呼ばれるファイルで、I<showtime> サブルーチンを +定義しましょう: + + print "I shan't be printed."; + + sub showtime { + print time; + } + +=begin original + +Simple enough. Now compile and run: + +=end original + +単純にして十分です。 +さあコンパイルして実行してみましょう: + + % cc -o showtime showtime.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` + % showtime showtime.pl + 818284590 + +=begin original + +yielding the number of seconds that elapsed between January 1, 1970 +(the beginning of the Unix epoch), and the moment I began writing this +sentence. + +=end original + +1970 年 1 月 1 日(UNIX 紀元の開始時点)からこのセンテンスを書いた時点までの +経過秒数が得られます。 + +=begin original + +In this particular case we don't have to call I<perl_run>, as we set +the PL_exit_flag PERL_EXIT_DESTRUCT_END which executes END blocks in +perl_destruct. + +=end original + +この特殊な状況では、私たちは I<perl_run> を呼ぶ必要はありません; +perl_destruct で END ブロックを実行する +PL_exit_flag PERL_EXIT_DESTRUCT_END をセットしているからです。 + +=begin original + +If you want to pass arguments to the Perl subroutine, you can add +strings to the C<NULL>-terminated C<args> list passed to +I<call_argv>. For other data types, or to examine return values, +you'll need to manipulate the Perl stack. That's demonstrated in +L<Fiddling with the Perl stack from your C program>. + +=end original + +Perl サブルーチンに引数を渡したいという場合、I<call_argv> に +渡される C<NULL> で終端されたリスト C<args> に文字列を追加することが +できます。 +他のデータ型を使ったり戻り値をチェックするには Perl スタックを +操作する必要があるでしょう。 +これは本ドキュメントの最後の +セクション L<Fiddling with the Perl stack from your C program> で +説明されています。 + +=head2 Evaluating a Perl statement from your C program + +(CプログラムからPerlの文を評価する) + +=begin original + +Perl provides two API functions to evaluate pieces of Perl code. +These are L<perlapi/eval_sv> and L<perlapi/eval_pv>. + +=end original + +Perl は Perl コードのかけら(pieces of Perl code)を評価するための二つの +API 関数を提供しています。 +L<perlapi/eval_sv> と L<perlapi/eval_pv> です。 + +=begin original + +Arguably, these are the only routines you'll ever need to execute +snippets of Perl code from within your C program. Your code can be as +long as you wish; it can contain multiple statements; it can employ +L<perlfunc/use>, L<perlfunc/require>, and L<perlfunc/do> to +include external Perl files. + +=end original + +これらの関数は、C プログラムの中で Perl のコードの断片を実行するのに +必要だったルーチンにすぎません。 +あなたはコードを好きなだけ長くでき、複数の文を含むことができます; +また、外部の Perl ファイルを取り込むために L<perlfunc/use>, +L<perlfunc/require>, L<perlfunc/do> を使うことができます。 + +=begin original + +I<eval_pv> lets us evaluate individual Perl strings, and then +extract variables for coercion into C types. The following program, +I<string.c>, executes three Perl strings, extracting an C<int> from +the first, a C<float> from the second, and a C<char *> from the third. + +=end original + +I<eval_pv> は独立した Perl の文字列を評価し、強制的に C の型へと +変数を展開します。 +以下に示すプログラムは I<string.c> は、三つの +Perl 文字列を実行し、最初のものを C<int >に、二番目のものを C<float> に、 +三番目のものを C<char *>へ 展開します。 + + #include <EXTERN.h> + #include <perl.h> + + static PerlInterpreter *my_perl; + + main (int argc, char **argv, char **env) + { + char *embedding[] = { "", "-e", "0" }; + + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct( my_perl ); + + perl_parse(my_perl, NULL, 3, embedding, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_run(my_perl); + + /** Treat $a as an integer **/ + eval_pv("$a = 3; $a **= 2", TRUE); + printf("a = %d\n", SvIV(get_sv("a", 0))); + + /** Treat $a as a float **/ + eval_pv("$a = 3.14; $a **= 2", TRUE); + printf("a = %f\n", SvNV(get_sv("a", 0))); + + /** Treat $a as a string **/ + eval_pv( + "$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);", TRUE); + printf("a = %s\n", SvPV_nolen(get_sv("a", 0))); + + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + } + +=begin original + +All of those strange functions with I<sv> in their names help convert Perl +scalars to C types. They're described in L<perlguts> and L<perlapi>. + +=end original + +名前に I<sv> の付いた奇妙な関数は Perl のスカラから C の型への変換を +手助けします。 +これらは L<perlguts> と L<perlapi> に記述されています。 + +=begin original + +If you compile and run I<string.c>, you'll see the results of using +I<SvIV()> to create an C<int>, I<SvNV()> to create a C<float>, and +I<SvPV()> to create a string: + +=end original + +I<string.c> をコンパイルして実行すれば、I<SvIV()> を使って C<int> を、 +I<SvNV()> を使って C<float> を、I<SvPV()> を使って文字列を生成した +結果を見ることになるでしょう。 + + a = 9 + a = 9.859600 + a = Just Another Perl Hacker + +=begin original + +In the example above, we've created a global variable to temporarily +store the computed value of our eval'ed expression. It is also +possible and in most cases a better strategy to fetch the return value +from I<eval_pv()> instead. Example: + +=end original + +先の例では、私たちが式を評価した値を一時的に格納するためのグローバル +変数を生成しました。 +これと同様なことが I<eval_pv()> の戻り値を取ることで可能であり、かつ +ほとんどの場合にはこれが良い戦略なのです。 +例えば: + + ... + SV *val = eval_pv("reverse 'rekcaH lreP rehtonA tsuJ'", TRUE); + printf("%s\n", SvPV_nolen(val)); + ... + +=begin original + +This way, we avoid namespace pollution by not creating global +variables and we've simplified our code as well. + +=end original + +このやり方によればグローバル変数を生成せず、またプログラムを単純に +したことによって名前空間の汚染を防ぎます。 + +=head2 Performing Perl pattern matches and substitutions from your C program + +(CプログラムからPerlのパターンマッチングと置換を使ってみる) + +=begin original + +The I<eval_sv()> function lets us evaluate strings of Perl code, so we can +define some functions that use it to "specialize" in matches and +substitutions: I<match()>, I<substitute()>, and I<matches()>. + +=end original + +関数 I<eval_pv> は Perl コードの文字列を評価するものなので、 +私たちはマッチや置換に「特化」(specilalize)するために使う +I<match()>, I<substitute()>, I<matches()>といった幾つかの関数を +定義できました。 + + I32 match(SV *string, char *pattern); + +=begin original + +Given a string and a pattern (e.g., C<m/clasp/> or C</\b\w*\b/>, which +in your C program might appear as "/\\b\\w*\\b/"), match() +returns 1 if the string matches the pattern and 0 otherwise. + +=end original + +文字列と C<m/clasp/> や C</\b\w*\b/> のようなパターン(これは +C プログラムでは"/\\b\\w*\\b/" のようになっているでしょう)を与えると、 +match() は文字列がパターンにマッチしたときには1を、そうでないときは +0 を返します。 + + int substitute(SV **string, char *pattern); + +=begin original + +Given a pointer to an C<SV> and an C<=~> operation (e.g., +C<s/bob/robert/g> or C<tr[A-Z][a-z]>), substitute() modifies the string +within the C<SV> as according to the operation, returning the number of +substitutions made. + +=end original + +C<SV> へのポインタと C<=~> 操作(C<s/bob/robert/g> もしくは +C<tr[A-Z][a-z]>)を与えると、substitue() はその操作に従って +C<SV> の中の文字列の書き換えを行って、置換の回数を返します。 + + SSize_t matches(SV *string, char *pattern, AV **matches); + +=begin original + +Given an C<SV>, a pattern, and a pointer to an empty C<AV>, +matches() evaluates C<$string =~ $pattern> in a list context, and +fills in I<matches> with the array elements, returning the number of matches +found. + +=end original + +C<SV>、パターン、空の C<AV> へのポインタを渡すと、 +matchs() はリストコンテキストで C<$string =~ $pattern> を評価して +I<matches> を配列の要素(メモリを割り当てます)で満たし、マッチした +回数を返します。 + +=begin original + +Here's a sample program, I<match.c>, that uses all three (long lines have +been wrapped here): + +=end original + +以下に示すのはサンプルプログラム I<match.c> で、三つの関数すべてを +使います(長い行は整形されてます)。 + + #include <EXTERN.h> + #include <perl.h> + + static PerlInterpreter *my_perl; + + /** my_eval_sv(code, error_check) + ** kinda like eval_sv(), + ** but we pop the return value off the stack + **/ + SV* my_eval_sv(SV *sv, I32 croak_on_error) + { + dSP; + SV* retval; + + PUSHMARK(SP); + eval_sv(sv, G_SCALAR); + + SPAGAIN; + retval = POPs; + PUTBACK; + + if (croak_on_error && SvTRUE(ERRSV)) + croak(SvPVx_nolen(ERRSV)); + + return retval; + } + + /** match(string, pattern) + ** + ** Used for matches in a scalar context. + ** + ** Returns 1 if the match was successful; 0 otherwise. + **/ + + I32 match(SV *string, char *pattern) + { + SV *command = newSV(0), *retval; + + sv_setpvf(command, "my $string = '%s'; $string =~ %s", + SvPV_nolen(string), pattern); + + retval = my_eval_sv(command, TRUE); + SvREFCNT_dec(command); + + return SvIV(retval); + } + + /** substitute(string, pattern) + ** + ** Used for =~ operations that + ** modify their left-hand side (s/// and tr///) + ** + ** Returns the number of successful matches, and + ** modifies the input string if there were any. + **/ + + I32 substitute(SV **string, char *pattern) + { + SV *command = newSV(0), *retval; + + sv_setpvf(command, "$string = '%s'; ($string =~ %s)", + SvPV_nolen(*string), pattern); + + retval = my_eval_sv(command, TRUE); + SvREFCNT_dec(command); + + *string = get_sv("string", 0); + return SvIV(retval); + } + + /** matches(string, pattern, matches) + ** + ** Used for matches in a list context. + ** + ** Returns the number of matches, + ** and fills in **matches with the matching substrings + **/ + + SSize_t matches(SV *string, char *pattern, AV **match_list) + { + SV *command = newSV(0); + SSize_t num_matches; + + sv_setpvf(command, "my $string = '%s'; @array = ($string =~ %s)", + SvPV_nolen(string), pattern); + + my_eval_sv(command, TRUE); + SvREFCNT_dec(command); + + *match_list = get_av("array", 0); + num_matches = av_top_index(*match_list) + 1; + + return num_matches; + } + + main (int argc, char **argv, char **env) + { + char *embedding[] = { "", "-e", "0" }; + AV *match_list; + I32 num_matches, i; + SV *text; + + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct(my_perl); + perl_parse(my_perl, NULL, 3, embedding, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + + text = newSV(0); + sv_setpv(text, "When he is at a convenience store and the " + "bill comes to some amount like 76 cents, Maynard is " + "aware that there is something he *should* do, something " + "that will enable him to get back a quarter, but he has " + "no idea *what*. He fumbles through his red squeezey " + "changepurse and gives the boy three extra pennies with " + "his dollar, hoping that he might luck into the correct " + "amount. The boy gives him back two of his own pennies " + "and then the big shiny quarter that is his prize. " + "-RICHH"); + + if (match(text, "m/quarter/")) /** Does text contain 'quarter'? **/ + printf("match: Text contains the word 'quarter'.\n\n"); + else + printf("match: Text doesn't contain the word 'quarter'.\n\n"); + + if (match(text, "m/eighth/")) /** Does text contain 'eighth'? **/ + printf("match: Text contains the word 'eighth'.\n\n"); + else + printf("match: Text doesn't contain the word 'eighth'.\n\n"); + + /** Match all occurrences of /wi../ **/ + num_matches = matches(text, "m/(wi..)/g", &match_list); + printf("matches: m/(wi..)/g found %d matches...\n", num_matches); + + for (i = 0; i < num_matches; i++) + printf("match: %s\n", + SvPV_nolen(*av_fetch(match_list, i, FALSE))); + printf("\n"); + + /** Remove all vowels from text **/ + num_matches = substitute(&text, "s/[aeiou]//gi"); + if (num_matches) { + printf("substitute: s/[aeiou]//gi...%lu substitutions made.\n", + (unsigned long)num_matches); + printf("Now text is: %s\n\n", SvPV_nolen(text)); + } + + /** Attempt a substitution **/ + if (!substitute(&text, "s/Perl/C/")) { + printf("substitute: s/Perl/C...No substitution made.\n\n"); + } + + SvREFCNT_dec(text); + PL_perl_destruct_level = 1; + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + } + +=begin original + +which produces the output (again, long lines have been wrapped here) + +=end original + +この出力は以下のようになります(繰り返しますが、長い行は +整形されています)。 + + match: Text contains the word 'quarter'. + + match: Text doesn't contain the word 'eighth'. + + matches: m/(wi..)/g found 2 matches... + match: will + match: with + + substitute: s/[aeiou]//gi...139 substitutions made. + Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts, + Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt + bck qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd + gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct + mnt. Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s + hs prz. -RCHH + + substitute: s/Perl/C...No substitution made. + +=head2 Fiddling with the Perl stack from your C program + +(C プログラムから Perl のスタックを見つけだす) + +=begin original + +When trying to explain stacks, most computer science textbooks mumble +something about spring-loaded columns of cafeteria plates: the last +thing you pushed on the stack is the first thing you pop off. That'll +do for our purposes: your C program will push some arguments onto "the Perl +stack", shut its eyes while some magic happens, and then pop the +results--the return value of your Perl subroutine--off the stack. + +=end original + +スタックを説明しようとするとき、ほとんどのコンピュータ科学の教科書は +食堂のプレート皿のばね仕掛けの仕切りのようなはっきりとしない解説をします: +最後にスタックに押し込んだ(push)ものが最初に取り出す(pop)ものです。 +これが、私たちの目的のために行うことです: あなたの C プログラムでは、幾つかの +引数を「Perl スタック」へプッシュして、魔法が掛かる間に目を閉じれば結果、 +つまりあなたの使った Perl サブルーチンの戻り値がスタックの一番上に +できます -- これをポップします。 + +=begin original + +First you'll need to know how to convert between C types and Perl +types, with newSViv() and sv_setnv() and newAV() and all their +friends. They're described in L<perlguts> and L<perlapi>. + +=end original + +まず第一に、あなたは newSViv()、sv_setnv()、newAV() そしてその他の +関数を使った C の型と Perl の型との間の変換の方法を知る必要があります。 +これらは L<perlguts> と L<perlapi> に記述されています。 + +=begin original + +Then you'll need to know how to manipulate the Perl stack. That's +described in L<perlcall>. + +=end original + +それから Perl スタックの操作方法を知る必要があります。 +これは L<perlcall> に説明があります。 + +=begin original + +Once you've understood those, embedding Perl in C is easy. + +=end original + +これらを理解すれば、C に Perl を組み込むのは簡単です。 + +=begin original + +Because C has no builtin function for integer exponentiation, let's +make Perl's ** operator available to it (this is less useful than it +sounds, because Perl implements ** with C's I<pow()> function). First +I'll create a stub exponentiation function in I<power.pl>: + +=end original + +C には整数のべき乗を行う組み込み関数がないので、Perl の ** 演算子を +使えるようにしましょう(これは思ったほど便利ではありません; なぜなら Perl は +** を C の I<pow()> 関数を使って実装しているからです)。 +最初に I<power.pl> にべき乗関数を作成しましょう。 + + sub expo { + my ($a, $b) = @_; + return $a ** $b; + } + +=begin original + +Now I'll create a C program, I<power.c>, with a function +I<PerlPower()> that contains all the perlguts necessary to push the +two arguments into I<expo()> and to pop the return value out. Take a +deep breath... + +=end original + +今度は I<expo()> への二つの引数をプッシュするのとそこからの戻り値 +をポップするに必要なすべての perlguts を含んでいる I<PerlPower()> と +いう関数を持った C プログラム I<power.c> を作ります。 +深く息をすって… + + #include <EXTERN.h> + #include <perl.h> + + static PerlInterpreter *my_perl; + + static void + PerlPower(int a, int b) + { + dSP; /* initialize stack pointer */ + ENTER; /* everything created after here */ + SAVETMPS; /* ...is a temporary variable. */ + PUSHMARK(SP); /* remember the stack pointer */ + XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */ + XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */ + PUTBACK; /* make local stack pointer global */ + call_pv("expo", G_SCALAR); /* call the function */ + SPAGAIN; /* refresh stack pointer */ + /* pop the return value from stack */ + printf ("%d to the %dth power is %d.\n", a, b, POPi); + PUTBACK; + FREETMPS; /* free that return value */ + LEAVE; /* ...and the XPUSHed "mortal" args.*/ + } + + int main (int argc, char **argv, char **env) + { + char *my_argv[] = { "", "power.pl" }; + + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct( my_perl ); + + perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_run(my_perl); + + PerlPower(3, 4); /*** Compute 3 ** 4 ***/ + + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + } + +=begin original + +Compile and run: + +=end original + +コンパイルして実行しましょう: + + % cc -o power power.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + + % power + 3 to the 4th power is 81. + +=head2 Maintaining a persistent interpreter + +(永続的インタプリタの保持) + +=begin original + +When developing interactive and/or potentially long-running +applications, it's a good idea to maintain a persistent interpreter +rather than allocating and constructing a new interpreter multiple +times. The major reason is speed: since Perl will only be loaded into +memory once. + +=end original + +対話的であるとか、長い時間実行される可能性のあるアプリケーションを +開発するとき、複数回新しいインタプリタを割り当てて構築するよりは永続的な +インタプリタを保持するのが良い考えです。 +主な理由はスピードです: (永続的にすることで)Perl はメモリーに一度しか +ロードされません。 + +=begin original + +However, you have to be more cautious with namespace and variable +scoping when using a persistent interpreter. In previous examples +we've been using global variables in the default package C<main>. We +knew exactly what code would be run, and assumed we could avoid +variable collisions and outrageous symbol table growth. + +=end original + +しかしながら永続的なインタプリタを使うときには、名前空間や変数の +スコープをより注意深く扱わねばならないでしょう。 +先の例では、私たちはデフォルトパッケージ C<main> でグローバル変数を +使いました。 +私たちは実際にあのコードが実行できることを知りましたが、変数の衝突や +シンボルテーブル拡大の限界に当たらないことを仮定していました。 + +=begin original + +Let's say your application is a server that will occasionally run Perl +code from some arbitrary file. Your server has no way of knowing what +code it's going to run. Very dangerous. + +=end original + +あなたのアプリケーションが、時折幾つかの任意のファイルから Perl コードが +実行されるサーバーであるとしましょう。 +あなたのサーバーは実行させたコードを知る術がありません。 +非常に危険です。 + +=begin original + +If the file is pulled in by C<perl_parse()>, compiled into a newly +constructed interpreter, and subsequently cleaned out with +C<perl_destruct()> afterwards, you're shielded from most namespace +troubles. + +=end original + +ファイルが C<perl_parse()> を使って引き込まれた場合、新しく構築された +インタプリタへコンパイルされ、後の C<perl_destruct()> で始末されます; +これによってほとんどの名前空間にまつわるトラブルから守られます。 + +=begin original + +One way to avoid namespace collisions in this scenario is to translate +the filename into a guaranteed-unique package name, and then compile +the code into that package using L<perlfunc/eval>. In the example +below, each file will only be compiled once. Or, the application +might choose to clean out the symbol table associated with the file +after it's no longer needed. Using L<perlapi/call_argv>, We'll +call the subroutine C<Embed::Persistent::eval_file> which lives in the +file C<persistent.pl> and pass the filename and boolean cleanup/cache +flag as arguments. + +=end original + +このシナリオにおいて名前空間の衝突を防ぐ一つの方法は、ファイル名を +ユニークであることが保証されているパッケージ名に変換し、それから +L<perlfunc/eval> を使ったコードにコンパイルするのです。 +先の例では、各ファイルは一回だけコンパイルされました。 +あるいは、アプリケーションはファイルに結び付けられたシンボルテーブルを +それが必要なくなった時点で掃除してしまうことを選択するかもしれません。 +L<perlapi/call_argv> を使うことで、私たちは C<persistent.pl> という +ファイルにあるサブルーチン C<Embed::Persistent::eval_file> を呼び出し、それに +ファイル名と cleanup/cache を表わすブール値を引数として渡します。 + +=begin original + +Note that the process will continue to grow for each file that it +uses. In addition, there might be C<AUTOLOAD>ed subroutines and other +conditions that cause Perl's symbol table to grow. You might want to +add some logic that keeps track of the process size, or restarts +itself after a certain number of requests, to ensure that memory +consumption is minimized. You'll also want to scope your variables +with L<perlfunc/my> whenever possible. + +=end original + +プロセスはそれぞれのファイルを使うごとに大きくなるということに +注意してください。 +それに加えて、C<AUTOLOAD> されたサブルーチンなどの条件によっても、 +Perl のシンボルテーブルは大きくなります。 +あなたはプロセスの大きさを記録しつづける何等かのロジックを +欲するかもしれませんし、あるいはメモリの消費量を最少にするために +特定回数のリクエストの後で自分自身を +再スタートするようにしたいかもしれません。 +また、可能であるときにはいつでも L<perlfunc/my> を使ってあなたの +使う変数を見通したいでしょう。 + + package Embed::Persistent; + #persistent.pl + + use strict; + our %Cache; + use Symbol qw(delete_package); + + sub valid_package_name { + my($string) = @_; + $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; + # second pass only for words starting with a digit + $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + + # Dress it up as a real package name + $string =~ s|/|::|g; + return "Embed" . $string; + } + + sub eval_file { + my($filename, $delete) = @_; + my $package = valid_package_name($filename); + my $mtime = -M $filename; + if(defined $Cache{$package}{mtime} + && + $Cache{$package}{mtime} <= $mtime) + { + # we have compiled this subroutine already, + # it has not been updated on disk, nothing left to do + print STDERR "already compiled $package->handler\n"; + } + else { + local *FH; + open FH, $filename or die "open '$filename' $!"; + local($/) = undef; + my $sub = <FH>; + close FH; + + #wrap the code into a subroutine inside our unique package + my $eval = qq{package $package; sub handler { $sub; }}; + { + # hide our variables within this block + my($filename,$mtime,$package,$sub); + eval $eval; + } + die $@ if $@; + + #cache it unless we're cleaning out each time + $Cache{$package}{mtime} = $mtime unless $delete; + } + + eval {$package->handler;}; + die $@ if $@; + + delete_package($package) if $delete; + + #take a look if you want + #print Devel::Symdump->rnew($package)->as_string, $/; + } + + 1; + + __END__ + + /* persistent.c */ + #include <EXTERN.h> + #include <perl.h> + + /* 1 = clean out filename's symbol table after each request, + 0 = don't + */ + #ifndef DO_CLEAN + #define DO_CLEAN 0 + #endif + + #define BUFFER_SIZE 1024 + + static PerlInterpreter *my_perl = NULL; + + int + main(int argc, char **argv, char **env) + { + char *embedding[] = { "", "persistent.pl" }; + char *args[] = { "", DO_CLEAN, NULL }; + char filename[BUFFER_SIZE]; + int exitstatus = 0; + + PERL_SYS_INIT3(&argc,&argv,&env); + if((my_perl = perl_alloc()) == NULL) { + fprintf(stderr, "no memory!"); + exit(1); + } + perl_construct(my_perl); + + PL_origalen = 1; /* don't let $0 assignment update the + proctitle or embedding[0] */ + exitstatus = perl_parse(my_perl, NULL, 2, embedding, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + if(!exitstatus) { + exitstatus = perl_run(my_perl); + + while(printf("Enter file name: ") && + fgets(filename, BUFFER_SIZE, stdin)) { + + filename[strlen(filename)-1] = '\0'; /* strip \n */ + /* call the subroutine, + passing it the filename as an argument */ + args[0] = filename; + call_argv("Embed::Persistent::eval_file", + G_DISCARD | G_EVAL, args); + + /* check $@ */ + if(SvTRUE(ERRSV)) + fprintf(stderr, "eval error: %s\n", SvPV_nolen(ERRSV)); + } + } + + PL_perl_destruct_level = 0; + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + exit(exitstatus); + } + +=begin original + +Now compile: + +=end original + +さあ、コンパイルしましょう: + + % cc -o persistent persistent.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` + +=begin original + +Here's an example script file: + +=end original + +スクリプトファイルの例です。 + + #test.pl + my $string = "hello"; + foo($string); + + sub foo { + print "foo says: @_\n"; + } + +=begin original + +Now run: + +=end original + +これを実行してみましょう: + + % persistent + Enter file name: test.pl + foo says: hello + Enter file name: test.pl + already compiled Embed::test_2epl->handler + foo says: hello + Enter file name: ^C + +=head2 Execution of END blocks + +(END ブロックの実行) + +=begin original + +Traditionally END blocks have been executed at the end of the perl_run. +This causes problems for applications that never call perl_run. Since +perl 5.7.2 you can specify C<PL_exit_flags |= PERL_EXIT_DESTRUCT_END> +to get the new behaviour. This also enables the running of END blocks if +the perl_parse fails and C<perl_destruct> will return the exit value. + +=end original + +伝統的に END ブロックは perl_run の最後に実行されてきました。 +これは、perl_run を呼び出さないアプリケーションで問題となります。 +perl 5.7.2 から、新しい振る舞いを取らせるために +C<PL_exit_flags |= PERL_EXIT_DESTRUCT_END> を指定できます。 +これはまた、もし perl_parse が失敗して C<perl_destruct> が終了値を返した +ときにも END ブロックを実行するようにします。 + +=head2 $0 assignments + +($0 への代入) + +=begin original + +When a perl script assigns a value to $0 then the perl runtime will +try to make this value show up as the program name reported by "ps" by +updating the memory pointed to by the argv passed to perl_parse() and +also calling API functions like setproctitle() where available. This +behaviour might not be appropriate when embedding perl and can be +disabled by assigning the value C<1> to the variable C<PL_origalen> +before perl_parse() is called. + +=end original + +perl スクリプトが $0 に値を代入すると、perl のランタイムは、perl_parse() に +渡された argv が指すメモリを更新して、利用可能なら setproctitle() のような +API 関数も呼び出すことによって、その値を "ps" で報告される +プログラム名として表示させようとします。 +この振る舞いは組み込み perl では不適切かもしれないので、perl_parse() が +呼び出される前に C<PL_origalen> に C<1> を代入することで無効にできます。 + +=begin original + +The F<persistent.c> example above is for instance likely to segfault +when $0 is assigned to if the C<PL_origalen = 1;> assignment is +removed. This because perl will try to write to the read only memory +of the C<embedding[]> strings. + +=end original + +例えば、上述の F<persistent.c> の例は、もし C<PL_origalen = 1;> 代入を +取り除くと、$0 が代入されたときにおそらくセグメンテーションフォルトが +起きるでしょう。 +これは C<embedding[]> 文字列の読み込み専用メモリに +書き込もうとするからです。 + +=head2 Maintaining multiple interpreter instances + +(複数のインタプリタのインスタンスを保持する) + +=begin original + +Some rare applications will need to create more than one interpreter +during a session. Such an application might sporadically decide to +release any resources associated with the interpreter. + +=end original + +ごく一部のアプリケーションでは、二つ以上のインタプリタを生成する +必要があるかもしれません。 +そのようなアプリケーションはインタプリタに結び付けられたリソースを +解放することを決定することがあるかもしれません。 + +=begin original + +The program must take care to ensure that this takes place I<before> +the next interpreter is constructed. By default, when perl is not +built with any special options, the global variable +C<PL_perl_destruct_level> is set to C<0>, since extra cleaning isn't +usually needed when a program only ever creates a single interpreter +in its entire lifetime. + +=end original + +プログラムは次のインタプリタが構築されるよりB<前に>、解放が +発生することに注意を払い、それを保証しなければなりません。 +デフォルトでは、perl が特殊なオプション付きでビルドされていなければ、 +グローバル変数 C<PL_perl_destruct_level> は C<0> に設定されています; +これはプログラムが生涯ただ一つのインタプリタを作っただけの +ときには、普通は余分な後始末が不要であるからです。 + +=begin original + +Setting C<PL_perl_destruct_level> to C<1> makes everything squeaky clean: + +=end original + +全てを始末させるためには C<PL_perl_destruct_level> を C<1> に設定します。 + + while(1) { + ... + /* reset global variables here with PL_perl_destruct_level = 1 */ + PL_perl_destruct_level = 1; + perl_construct(my_perl); + ... + /* clean and reset _everything_ during perl_destruct */ + PL_perl_destruct_level = 1; + perl_destruct(my_perl); + perl_free(my_perl); + ... + /* let's go do it again! */ + } + +=begin original + +When I<perl_destruct()> is called, the interpreter's syntax parse tree +and symbol tables are cleaned up, and global variables are reset. The +second assignment to C<PL_perl_destruct_level> is needed because +perl_construct resets it to C<0>. + +=end original + +I<perl_destruct()> が呼ばれたとき、インタプリタの構文解析木と +シンボルテーブルは始末され、そしてグローバル変数がリセットされます。 +C<PL_perl_destruct_level> への第 2 引数は、perl_construct を C<0> に +リセットするために必要です。 + +=begin original + +Now suppose we have more than one interpreter instance running at the +same time. This is feasible, but only if you used the Configure option +C<-Dusemultiplicity> or the options C<-Dusethreads -Duseithreads> when +building perl. By default, enabling one of these Configure options +sets the per-interpreter global variable C<PL_perl_destruct_level> to +C<1>, so that thorough cleaning is automatic and interpreter variables +are initialized correctly. Even if you don't intend to run two or +more interpreters at the same time, but to run them sequentially, like +in the above example, it is recommended to build perl with the +C<-Dusemultiplicity> option otherwise some interpreter variables may +not be initialized correctly between consecutive runs and your +application may crash. + +=end original + +現在、二つ以上のインタプリタのインスタンスを同時に実行することが +サポートされています。 +これは可能なことですが、Perlビルドしたときに Configure オプション +C<-Dusemultiplicity> か C<-Dusethreads -Duseithreads> を +使ったときのみです。 +デフォルトでは、これらの Configure オプションの一つが有効になると +インタプリタ単位のグローバル変数 C<PL_perl_destruct_level> が C<1> に +設定され、これによって徹底的なクリーニングは自動的で、インタプリタ変数は +正しく初期化されます。 +同時に複数のインタプリタを実行するつもりがない場合でも、上述の例のように +順番に実行させるつもりなら、C<-Dusemultiplicity> オプションをつけて +perl をビルドすることを推奨します; さもなければ連続した実行の間に +インタプリタ変数が正しく初期化されずに、アプリケーションが +クラッシュするかもしれません。 + +=begin original + +See also L<perlxs/Thread-aware system interfaces>. + +=end original + +L<perlxs/Thread-aware system interfaces> も参照してください。 + +=begin original + +Using C<-Dusethreads -Duseithreads> rather than C<-Dusemultiplicity> +is more appropriate if you intend to run multiple interpreters +concurrently in different threads, because it enables support for +linking in the thread libraries of your system with the interpreter. + +=end original + +もし、異なるスレッドで同時に複数のインタプリタを実行するつもりなら、 +C<-Dusemultiplicity> ではなく C<-Dusethreads -Duseithreads> がより適切です; +なぜならこれはインタプリタにシステムのスレッドライブラリを +リンクすることへの対応を有効にするからです。 + +=begin original + +Let's give it a try: + +=end original + +試してみましょう: + + #include <EXTERN.h> + #include <perl.h> + + /* we're going to embed two interpreters */ + + #define SAY_HELLO "-e", "print qq(Hi, I'm $^X\n)" + + int main(int argc, char **argv, char **env) + { + PerlInterpreter *one_perl, *two_perl; + char *one_args[] = { "one_perl", SAY_HELLO }; + char *two_args[] = { "two_perl", SAY_HELLO }; + + PERL_SYS_INIT3(&argc,&argv,&env); + one_perl = perl_alloc(); + two_perl = perl_alloc(); + + PERL_SET_CONTEXT(one_perl); + perl_construct(one_perl); + PERL_SET_CONTEXT(two_perl); + perl_construct(two_perl); + + PERL_SET_CONTEXT(one_perl); + perl_parse(one_perl, NULL, 3, one_args, (char **)NULL); + PERL_SET_CONTEXT(two_perl); + perl_parse(two_perl, NULL, 3, two_args, (char **)NULL); + + PERL_SET_CONTEXT(one_perl); + perl_run(one_perl); + PERL_SET_CONTEXT(two_perl); + perl_run(two_perl); + + PERL_SET_CONTEXT(one_perl); + perl_destruct(one_perl); + PERL_SET_CONTEXT(two_perl); + perl_destruct(two_perl); + + PERL_SET_CONTEXT(one_perl); + perl_free(one_perl); + PERL_SET_CONTEXT(two_perl); + perl_free(two_perl); + PERL_SYS_TERM(); + } + +=begin original + +Note the calls to PERL_SET_CONTEXT(). These are necessary to initialize +the global state that tracks which interpreter is the "current" one on +the particular process or thread that may be running it. It should +always be used if you have more than one interpreter and are making +perl API calls on both interpreters in an interleaved fashion. + +=end original + +PERL_SET_CONTEXT() の呼び出しに注意してください。 +実行されている個々のプロセスやスレッドで、どのインタプリタが +「カレント」なのかを追跡するグローバルな状態を初期化するために必要です。 +もし複数のインタプリタがあって、両方のインタプリタに交互に perl API +呼び出しを行うなら、常にこれを行うべきです。 + +=begin original + +PERL_SET_CONTEXT(interp) should also be called whenever C<interp> is +used by a thread that did not create it (using either perl_alloc(), or +the more esoteric perl_clone()). + +=end original + +(perl_alloc() か、より難解な perl_clone() を使って、) C<interp> を +作ったのではないスレッドによって使われるときはいつでも、 +PERL_SET_CONTEXT(interp) も呼び出されるべきです。 + +=begin original + +Compile as usual: + +=end original + +いつもと同じようにコンパイルします: + + % cc -o multiplicity multiplicity.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` + +=begin original + +Run it, Run it: + +=end original + +実行、実行: + + % multiplicity + Hi, I'm one_perl + Hi, I'm two_perl + +=head2 Using Perl modules, which themselves use C libraries, from your C +program + +(C プログラムから、C のライブラリを使っている Perl モジュールを使う) + +=begin original + +If you've played with the examples above and tried to embed a script +that I<use()>s a Perl module (such as I<Socket>) which itself uses a C or C++ +library, this probably happened: + +=end original + +あなたがこれまでにでてきた例を使っていて、(I<Socket> のような)そ +れ自身が C や C++ のライブラリを使っている Perl モジュールを +I<use()> しているスクリプトを埋め込もうとしているのであれば、こうなる +可能性があります。 + + Can't load module Socket, dynamic loading not available in this perl. + (You may need to build a new perl executable which either supports + dynamic loading or has the Socket module statically linked into it.) + +=begin original + +What's wrong? + +=end original + +なにがまずいのでしょう? + +=begin original + +Your interpreter doesn't know how to communicate with these extensions +on its own. A little glue will help. Up until now you've been +calling I<perl_parse()>, handing it NULL for the second argument: + +=end original + +あなたの使うインタプリタはこういったエクステンションと +どのように交信するのかを知りません。 +ちょっとした糊(glue)が助けになります。 +これまでは、I<perl_parse()> を呼び出すときにはその第二引数として +NULL を使っていました: + + perl_parse(my_perl, NULL, argc, my_argv, NULL); + +=begin original + +That's where the glue code can be inserted to create the initial contact +between Perl and linked C/C++ routines. Let's take a look some pieces of +I<perlmain.c> to see how Perl does this: + +=end original + +ここは Perl と、リンクされた C/C++ ルーチンとの間の初期化時の交信を +生成するために挿入することのできる糊コード(glue code)の場所です。 +Perl がどのようにこれを行っているのかを知るために、I<perlmain.c> の +一部を見てみましょう。 + + static void xs_init (pTHX); + + EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); + EXTERN_C void boot_Socket (pTHX_ CV* cv); + + EXTERN_C void + xs_init(pTHX) + { + char *file = __FILE__; + /* DynaLoader is a special case */ + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); + newXS("Socket::bootstrap", boot_Socket, file); + } + +=begin original + +Simply put: for each extension linked with your Perl executable +(determined during its initial configuration on your +computer or when adding a new extension), +a Perl subroutine is created to incorporate the extension's +routines. Normally, that subroutine is named +I<Module::bootstrap()> and is invoked when you say I<use Module>. In +turn, this hooks into an XSUB, I<boot_Module>, which creates a Perl +counterpart for each of the extension's XSUBs. Don't worry about this +part; leave that to the I<xsubpp> and extension authors. If your +extension is dynamically loaded, DynaLoader creates I<Module::bootstrap()> +for you on the fly. In fact, if you have a working DynaLoader then there +is rarely any need to link in any other extensions statically. + +=end original + +あなたの使う Perl の実行ファイルにリンクされているエクステンション毎に、 +そのエクステンションのルーチンを組み込むための Perl サブルーチンが +生成されます。 +通常はこういったサブルーチンは I<Module::bootstrap()> という名称で、 +あなたが I<use Module> としたときに起動されます。 +次にこれは、各エクステンションの XSUB に対する Perl の counterpart として +生成されるXSUB I<boot_Module> にフックされます。 +この部分に関して心配することはありません; I<xsubpp> と、エクステンションの +作者に任せましょう。 +あなたの使うエクステンションが動的ロードを必要とするならば、 +DynaLoader はあなたのためにその場で I<Module::bootstrap()> を生成します。 +実際のところ、あなたが DynaLoader を使っているのであれば、他の +エクステンションを静的にリンクする必要性はほとんどないでしょう。 + +=begin original + +Once you have this code, slap it into the second argument of I<perl_parse()>: + +=end original + +このコードを一度書いてしまえば、それを I<perl_parse()> の第二引数に +置けます: + + perl_parse(my_perl, xs_init, argc, my_argv, NULL); + +=begin original + +Then compile: + +=end original + +そしてコンパイルします: + + % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + + % interp + use Socket; + use SomeDynamicallyLoadedModule; + + print "Now I can use extensions!\n"' + +=begin original + +B<ExtUtils::Embed> can also automate writing the I<xs_init> glue code. + +=end original + +B<ExtUtils::Embed> も I<xs_init> 糊コードを書くことを +自動化できます。 + + % perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c + % cc -c perlxsi.c `perl -MExtUtils::Embed -e ccopts` + % cc -c interp.c `perl -MExtUtils::Embed -e ccopts` + % cc -o interp perlxsi.o interp.o `perl -MExtUtils::Embed -e ldopts` + +=begin original + +Consult L<perlxs>, L<perlguts>, and L<perlapi> for more details. + +=end original + +詳しくは L<perlxs>, L<perlguts>, L<perlapi> を参照してください。 + +=head2 Using embedded Perl with POSIX locales + +(POSIX ロケールで組み込み Perl を使う) + +=begin original + +(See L<perllocale> for information about these.) +When a Perl interpreter normally starts up, it tells the system it wants +to use the system's default locale. This is often, but not necessarily, +the "C" or "POSIX" locale. Absent a S<C<"use locale">> within the perl +code, this mostly has no effect (but see L<perllocale/Not within the +scope of "use locale">). Also, there is not a problem if the +locale you want to use in your embedded Perl is the same as the system +default. However, this doesn't work if you have set up and want to use +a locale that isn't the system default one. Starting in Perl v5.20, you +can tell the embedded Perl interpreter that the locale is already +properly set up, and to skip doing its own normal initialization. It +skips if the environment variable C<PERL_SKIP_LOCALE_INIT> is set (even +if set to 0 or C<"">). A Perl that has this capability will define the +C pre-processor symbol C<HAS_SKIP_LOCALE_INIT>. This allows code that +has to work with multiple Perl versions to do some sort of work-around +when confronted with an earlier Perl. + +=end original + +(これらに関する情報については L<perllocale> を参照してください。) +Perl インタプリタが普通に開始したとき、システムのデフォルトのロケールを +使うということをシステムに伝えます。 +これはたいてい "C" または "POSIX" ロケールですが、そうである必要はありません。 +perl のコードに S<C<"use locale">> がなければ、これはほとんど何の影響も +ありません (しかし L<perllocale/Not within the +scope of "use locale"> を参照してください)。 +また、組み込み Perl で使いたいロケールがシステムのデフォルトと同じ場合は +問題になりません。 +しかし、システムのデフォルトではないロケールを設定して使いたい場合は +動作しません。 +Perl v5.20 から、ロケールは既に適切に設定されているので、通常の初期化を +飛ばすように組み込み Perl インタプリタに伝えられます。 +環境変数 C<PERL_SKIP_LOCALE_INIT> が設定されていれば (たとえ +0 または C<""> に設定されていても) 飛ばされます。 +この機能のある Perl は C プリプロセッサシンボル C<HAS_SKIP_LOCALE_INIT> が +設定されています。 +これにより、古い Perl に直面したときに、複数の Perl バージョンに対して何らかの +回避策をとれるようになります。 + +=head1 Hiding Perl_ + +(Perl_ を隠す) + +=begin original + +If you completely hide the short forms of the Perl public API, +add -DPERL_NO_SHORT_NAMES to the compilation flags. This means that +for example instead of writing + +=end original + +もし Perl public API の短い形式を完全に隠したいなら、 +コンパイルオプションに -DPERL_NO_SHORT_NAMES を追加してください。 +これは、例えば以下のように書く代わりに: + + warn("%d bottles of beer on the wall", bottlecount); + +=begin original + +you will have to write the explicit full form + +=end original + +以下のように明示的に完全な形式で書く必要があります: + + Perl_warn(aTHX_ "%d bottles of beer on the wall", bottlecount); + +=begin original + +(See L<perlguts/"Background and PERL_IMPLICIT_CONTEXT"> for the explanation +of the C<aTHX_>. ) Hiding the short forms is very useful for avoiding +all sorts of nasty (C preprocessor or otherwise) conflicts with other +software packages (Perl defines about 2400 APIs with these short names, +take or leave few hundred, so there certainly is room for conflict.) + +=end original + +(C<aTHX_> の説明については +L<perlguts/"Background and PERL_IMPLICIT_CONTEXT"> を参照してください。) +短い形式を隠すことは、その他のソフトウェアパッケージとのあらゆる種類の +不快なもの(C プリプロセッサやその他のもの)との衝突を避けるためにとても +便利です。 + +=head1 MORAL + +=begin original + +You can sometimes I<write faster code> in C, but +you can always I<write code faster> in Perl. Because you can use +each from the other, combine them as you wish. + +=end original + +あなたは時々 C で B<より速いコードを> 書くことができるかもしれませんが、 +あなた常に Perl で B<コードをより早く> 書くことができるのです。 +これは片方でもう片方のものを作ることができ、望むままに +組み合わせることができるからです。 + +=head1 AUTHOR + +=begin original + +Jon Orwant <F<orwan****@media*****>> and Doug MacEachern +<F<dougm****@coval*****>>, with small contributions from Tim Bunce, Tom +Christiansen, Guy Decoux, Hallvard Furuseth, Dov Grobgeld, and Ilya +Zakharevich. + +=end original + +Jon Orwant <F<orwan****@media*****>> と Doug MacEachern +<F<dougm****@coval*****>>; さらに Tim Bunce, Tom Christiansen, +Guy Decoux, Hallvard Furuseth, Dov Grobgeld, Ilya Zakharevich からの +小さな貢献によります。 + +=begin original + +Doug MacEachern has an article on embedding in Volume 1, Issue 4 of +The Perl Journal ( http://www.tpj.com/ ). Doug is also the developer of the +most widely-used Perl embedding: the mod_perl system +(perl.apache.org), which embeds Perl in the Apache web server. +Oracle, Binary Evolution, ActiveState, and Ben Sugars's nsapi_perl +have used this model for Oracle, Netscape and Internet Information +Server Perl plugins. + +=end original + +Doug MacEachern は The Perl Journal ( http://www.tpj.com/ ) の +Volume 1, Issue 4 に組み込みの記事を書いています。 +Doug はまた、もっとも広く使われている Perl 組み込みの作者です: +mod_perl (perl.apache.org) は Apache ウェブサーバに Perl を組み込みます。 +Oracle, Binary Evolution, ActiveState, Ben Sugars の nsapi_perl は +このモデルを Oracle, Netscape, Internet Information Server の +Perl プラグインに使っています。 + +=head1 COPYRIGHT + +Copyright (C) 1995, 1996, 1997, 1998 Doug MacEachern and Jon Orwant. All +Rights Reserved. + +This document may be distributed under the same terms as Perl itself. + +=begin meta + +Translate: KIMURA Koichi (5.005) +Update: SHIRAKATA Kentaro <argra****@ub32*****> (5.10.0-) +Status: completed + +=end meta +