\chapter{他のアプリケーションへの Python の埋め込み
     \label{embedding}}

前章では、 Python を拡張する方法、すなわち C 関数のライブラリを
Python に結びつけて機能を拡張する方法について述べました。
同じようなことを別の方法でも実行できます: それは、自分の C/\Cpp{}
アプリケーションに Python を埋め込んで機能を強化する、というものです。
埋め込みを行うことで、アプリケーションの何らかの機能を C や \Cpp
の代わりに Python で実装できるようになります。
埋め込みは多くの用途で利用できます; ユーザが Python でスクリプトを書き、
アプリケーションを自分好みに仕立てられるようにする、というのが
その一例です。プログラマが、特定の機能を Python でより楽に書ける場合に
自分自身のために埋め込みを行うこともできます。

Python の埋め込みは Python の拡張と似ていますが、全く同じという
わけではありません。その違いは、Python を拡張した場合には
アプリケーションのメインプログラムは依然として Python インタプリタ
である一方、 Python を組み込みんだ場合には、メインプログラムには
Python が関係しない --- その代わりに、アプリケーションのある一部分
が時折 Python インタプリタを呼び出して何らかの Python コードを
実行させる --- かもしれない、ということです。

従って、 Python の埋め込みを行う場合、自作のメインプログラムを
提供しなければなりません。メインプログラムがやらなければならないこと
の一つに、 Python インタプリタの初期化があります。とにかく少なくとも
関数 \cfunction{Py_Initialize()} 
(Mac OS なら\cfunction{PyMac_Initialize()}) を呼び出さねばなりません。
オプションとして、Python 側にコマンドライン引数を渡すために関数呼び出し
を行います。その後、アプリケーションのどこでもインタプリタを
呼び出せるようになります。

インタプリタを呼び出すには、異なるいくつかの方法があります:
Python 文が入った文字列を\cfunction{PyRun_SimpleString()} に渡す、
stdio ファイルポインタとファイル名 (これはエラーメッセージ内で
コードを識別するためだけのものです) を
\cfunction{PyRun_SimpleFile()} に渡す、といった具合です。
これまでの各章で説明した低水準の操作を呼び出して、Python オブジェクトを
構築したり使用したりもできます。

Python の埋め込みを行っている簡単なデモは、ソース配布物の
\file{Demo/embed/} ディレクトリにあります。


\begin{seealso}
  \seetitle[../api/api.html]{Python/C API リファレンスマニュアル}{
Python  C インタフェースの詳細はこのマニュアルに書かれています。
必要な情報の大部分はここにあるはずです。}
\end{seealso}


\section{高水準の埋め込み
         \label{high-level-embedding}}

Python の埋め込みの最も簡単な形式は、超高水準インタフェースの
利用です。
このインタフェースは、アプリケーションとやり取りする必要がない
Python スクリプトを実行するためのものです。
例えばこれは、一つのファイル上で何らかの操作を実現するのに利用
できます。

\begin{verbatim}
#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}
\end{verbatim}

上のコードでは、まず Python インタプリタを
\cfunction{Py_Initialize()} で起動し、続いてハードコードされた
Python スクリプトで日付と時間の出力を実行します。
その後、\cfunction{Py_Finalize()} の呼び出しでインタプリタを
終了し, プログラムの終了に続きます。
実際のプログラムでは、Python スクリプトを他のソース、おそらく
テキストエディタルーチンやファイル、データベースから取り出したいと
考えるかもしれません。Python コードをファイルから取り出すには、
\cfunction{PyRun_SimpleFile()} 関数を使うのがよいでしょう。
この関数はメモリを確保して、ファイルの内容をロードする手間を
省いてくれます。


\section{超高水準の埋め込みから踏み出す: 概要
         \label{lower-level-embedding}}

高水準インタフェースは、断片的な Python コードをアプリケーションから
実行できるようにしてくれますが、アプリケーションと Python コードの
間でのデータのやり取りは、控えめに言っても煩わしいものです。
データのやり取りをしたいなら、より低水準のインタフェース呼び出しを
利用しなくてはなりません。より多く C コードを書かねばならない
代わりに、ほぼ何でもできるようになります。

Python の拡張と埋め込みは、趣旨こそ違え、同じ作業であるということ
に注意せねばなりません。これまでの章で議論してきたトピックの
ほとんどが埋め込みでもあてはまります。これを示すために、
Python から C への拡張を行うコードが実際には何をするか考えて
みましょう:

\begin{enumerate}
    \item データ値を Python から C に変換する。
    \item 変換された値を使って C ルーチンの関数呼び出しを行い、
    \item 呼び出しで得られたデータ値 C から Python に変換する。
\end{enumerate}

Python を埋め込む場合には、インタフェースコードが行う作業は以下の
ようになります:

\begin{enumerate}
    \item データ値を C から Python に変換する。
    \item 変換された値を使って Python インタフェースルーチンの
関数呼び出しを行い、
    \item 呼び出しで得られたデータ値 Python から C に変換する。
\end{enumerate}

一見して分かるように、データ変換のステップは、言語間でデータを
転送する方向が変わったのに合わせて単に入れ替えただけです。
唯一の相違点は、データ変換の間にあるルーチンです。
拡張を行う際には C ルーチンを呼び出しますが、埋め込みの
際には Python ルーチンを呼び出します。

この章では、Python から C へ、そしてその逆へとデータを変換する
方法については議論しません。また、正しい参照の使い方やエラーの
扱い方についてすでに理解しているものと仮定します。
これらの側面についてはインタプリタの拡張と何ら変わるところが
ないので、必要な情報については以前の章を参照できます。


\section{純粋な埋め込み
         \label{pure-embedding}}

最初に例示するプログラムは、Python スクリプト内の関数を実行する
ためのものです。超高水準インタフェースに関する節で挙げた
例と同様に、Python インタプリタはアプリケーションと直接
やりとりはしません (が、次の節でやりとりするよう変更します)。

Python スクリプト内で定義されている関数を実行するための
コードは以下のようになります:

\verbatiminput{run-func.c}

このコードは\code{argv[1]} を使って Python スクリプトをロードし、
\code{argv[2]} 内に指定された名前の関数を呼び出します。
関数の整数引数は \code{argv} 配列中の他の値になります。
このプログラムをコンパイルしてリンクし (できた実行可能形式を
\program{call} と呼びましょう)、以下のような Python
スクリプトを実行することにします:

\begin{verbatim}
def multiply(a,b):
    print "Will compute", a, "times", b
    c = 0
    for i in range(0, a):
        c = c + b
    return c
\end{verbatim}

実行結果は以下のようになるはずです:

\begin{verbatim}
$ call multiply multiply 3 2
Will compute 3 times 2
Result of call: 6
\end{verbatim} % $

この程度の機能を実現するにはプログラムがいささか大きすぎますが、
ほとんどは Python から C へのデータ変換やエラー報告のための
コードです。Python の埋め込みという観点から最も興味深い部分は
以下のコード、

\begin{verbatim}
    Py_Initialize();
    pName = PyString_FromString(argv[1]);
    /* pName のエラーチェックは省略している */
    pModule = PyImport_Import(pName);
\end{verbatim}

から始まる部分です。

インタプリタの初期化後、スクリプトは
\cfunction{PyImport_Import()} を使って読み込まれます。
このルーチンは Python 文字列を引数に取る必要があり、
データ変換ルーチン\cfunction{PyString_FromString()} で
構築します。

\begin{verbatim}
    pFunc = PyObject_GetAttrString(pModule, argv[2]);
    /* pFunc は新たな参照 */

    if (pFunc && PyCallable_Check(pFunc)) {
        ...
    }
    Py_XDECREF(pFunc);
\end{verbatim}

ひとたびスクリプトが読み込まれると、
\cfunction{PyObject_GetAttrString()} を使って必要な名前を取得
できます。名前がスクリプト中に存在し、取得したオブジェクトが
呼び出し可能オブジェクトであれば、このオブジェクトが関数であると
考えて差し支えないでしょう。そこでプログラムは定石どおりに引数の
タプル構築に進みます。その後、Python 関数を以下のコードで
呼び出します:

\begin{verbatim}
    pValue = PyObject_CallObject(pFunc, pArgs);
\end{verbatim}

関数が処理を戻す際、\code{pValue} は \NULL{} になるか、
関数の戻り値への参照が入っています。
値を調べた後には忘れずに参照を解放してください。


\section{埋め込まれた Python の拡張
         \label{extending-with-embedding}}

ここまでは、埋め込み Python インタプリタはアプリケーション本体の
機能にアクセスする手段がありませんでした。
Python API を使うと、埋め込みインタプリタを拡張することで
アプリケーション本体へのアクセスを可能にします。
つまり、アプリケーションで提供されているルーチンを使って、
埋め込みインタプリタを拡張するのです。
複雑なことのように思えますが、それほどひどいわけではありません。
さしあたって、アプリケーションが Python インタプリタを起動したと
いうことをちょっと忘れてみてください。その代わり、アプリケーションが
サブルーチンの集まりで、あたかも普通の Python 拡張モジュールを
書くかのように、Python から各ルーチンにアクセスできるようにする
グルー(glue, 糊) コードを書くと考えてください。例えば以下のようにです:

\begin{verbatim}
static int numargs=0;

/* アプリケーションのコマンドライン引数の個数を返す */
static PyObject*
emb_numargs(PyObject *self, PyObject *args)
{
    if(!PyArg_ParseTuple(args, ":numargs"))
        return NULL;
    return Py_BuildValue("i", numargs);
}

static PyMethodDef EmbMethods[] = {
    {"numargs", emb_numargs, METH_VARARGS,
     "Return the number of arguments received by the process."},
    {NULL, NULL, 0, NULL}
};
\end{verbatim}

上のコードを \cfunction{main()} 関数のすぐ上に挿入します。
また、以下の二つの文を\cfunction{Py_Initialize()} の直後
に挿入します:

\begin{verbatim}
    numargs = argc;
    Py_InitModule("emb", EmbMethods);
\end{verbatim}

これら二つの行は\code{numargs} 変数を初期化し、
埋め込み Python インタプリタから\function{emb.numargs()} 関数に
アクセスできるようにします。これらの拡張モジュール関数を使うと、
Python スクリプトは

\begin{verbatim}
import emb
print "Number of arguments", emb.numargs()
\end{verbatim}

のようなことができます。

実際のアプリケーションでは、こうしたメソッドでアプリケーション内の
API を Python に公開することになります。


%\section{For the future}
%
%You don't happen to have a nice library to get textual
%equivalents of numeric values do you :-) ?
%Callbacks here ? (I may be using information from that section
%?!)
%threads
%code examples do not really behave well if errors happen
% (what to watch out for)


\section{\Cpp による Python の埋め込み
     \label{embeddingInCplusplus}}

\Cpp{} プログラム中にも Python を埋め込めます; 厳密に言うと、
どうやって埋め込むかは使っている\Cpp{} 処理系の詳細に依存します;
一般的には、メインプログラムを\Cpp で書き、\Cpp{} コンパイラ
を使ってプログラムをコンパイル・リンクする必要があるでしょう。
Python 自体を \Cpp でコンパイルしなおす必要はありません。


\section{リンクに関する要件
         \label{link-reqs}}

Python ソースと一緒についてくる\program{configure} スクリプトは
動的にリンクされる拡張モジュールが必要とするシンボルを公開するよう
ただしく Python をビルドしますが、この機能は
Python ライブラリを静的に埋め込むようなアプリケーションには
継承されません。少なくとも \UNIX{} ではそうです。
これは、アプリケーションが静的な実行時ライブラリ (\file{libpython.a})
にリンクされていて、かつ (\file{.so} ファイルとして実装されている) 
動的ロードされるような拡張モジュールをロードする必要がある場合に
起きる問題です。

問題になるのは、拡張モジュールが使うあるエントリポイントが
Python ランタイムだけで定義されているという状況です。
埋め込みを行うアプリケーション側がこうしたエントリポイントを
全く使わない場合、リンカによってはエントリポイントを最終的に
生成される実行可能形式のシンボルテーブル内に含めません。
こうした場合、リンカに追加のオプションを与えて、これらのシンボルを
除去しないよう教える必要があります。

プラットフォームごとに正しいオプションを決めるのはかなり困難です、
とはいえ、幸運なことに、オプションは Python のビルド設定内にすでに
あります。インストール済みの Python インタプリタからオプションを
取り出すには、対話インタプリタを起動して、以下のような短い
セッションを実行します:

\begin{verbatim}
>>> import distutils.sysconfig
>>> distutils.sysconfig.get_config_var('LINKFORSHARED')
'-Xlinker -export-dynamic'
\end{verbatim}
\refstmodindex{distutils.sysconfig}

表示された文字列の内容が、ビルド時に使うべきオプションです。
文字列が空であれば、特に追加すべきオプションはありません。
\constant{LINKFORSHARED} の定義内容は、 Python のトップレベル
\file{Makefile} 内の同名の変数に対応しています。



