4.1 型どおりのアプローチ

Windows での拡張モジュールのビルドには、Unix と同じように、 distutils パッケージを使ったビルド作業の制御と 手動の二通りのアプローチがあります。 distutils によるアプローチはほとんどの拡張モジュールで うまくいきます; distutils を使った拡張モジュールの ビルドとパッケージ化については、 Python モジュールの配布 に あります。この節では、C や C++で書かれた Python 拡張モジュール を手動でビルドするアプローチについて述べます。

以下の説明に従って拡張モジュールをビルドするには、インストールされている Python と同じバージョンの Python のソースコードを持っていなければ なりません。また、 Microsoft Visual C++ ``Developer Studio'' が必要になります; プロジェクトファイルは VC++ バージョン 6 向けのものが提供されていますが、以前のバージョンの VC++も 使えます。ここで述べる例題のファイルは、Python ソースコードと 共に配布されており、PC\example_nt\ ディレクトリにあります。

  1. 例題ファイルをコピーする
    example_nt ディレクトリは PC ディレクトリのサブディレクトリ になっています。これは PC 関連の全てのファイルをソースコード配布物内の 同じディレクトリに置くための措置です。とはいえ実際には、 example_nt ディレクトリはPC の下では利用できません。 そこで、まずこのディレクトリを一階層上にコピーして、 example_ntPC および Include と同じ 階層のディレクトリになるようにします。 以降の作業は、移動先の新しいディレクトリ内で行ってください。

  2. プロジェクトを開く
    VC++から、 ファイル > ワークスペースを開く ダイアログメニューを選択します (ファイル > 開く ではありません!)。ディレクトリ階層を辿って、example_nt をコピーしたディレクトリ 内のexample.dsw を選択 し、「開く」をクリックします。

  3. 例題の DLL をビルドする
    設定が全て正しく行われているか調べるために、ビルドしてみます:

    1. ビルド構成を選びます。このステップは省略できます。 ビルド > アクティブな構成の選択 を選び、 example - Win32 リリース または example - Win32 デバッグ を選びます。 このステップを飛ばすと、VC++ はデフォルトでデバッグ構成を使います。

    2. DLL をビルドします。デバッグモードなら、 ビルド > example_d.dll のビルド を、 リリースモードなら ビルド > example.dll を選びます。 この操作で。全ての中間ファイルおよび最終ファイルが、上のビルド構成 で選んだ構成に従ってDebug または Release という名前の ディレクトリに生成されます。

  4. デバッグモードの DLL をテストする
    デバッグビルドが成功したら、コマンドプロンプトを起動し、 example_nt\Debug ディレクトリに移動して ください。以下のセッション通りにコマンドを実行できるはずです (C> は DOS コマンドのプロンプト、>>> は Python のプロンプトです; ビルド情報や様々なデバッグ出力は、 ここに示したスクリーン出力と一致しないこともあるので注意して下さい):

    C>..\..\PCbuild\python_d
    Adding parser accelerators ...
    Done.
    Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32
    Type "copyright", "credits" or "license" for more information.
    >>> import example
    [4897 refs]
    >>> example.foo()
    Hello, world
    [4903 refs]
    >>>
    

    おめでとうございます! とうとう初めての Python 拡張モジュールのビルド に成功しましたね。

  5. 自分用にプロジェクトを作成する
    プロジェクト用のディレクトリを適当な名前で作成してください。 自作の C ソースコードをディレクトリ内にコピーします。 モジュールのソースコードファイル名は必ずしもモジュール名と 一致している必要はありませんが、初期化関数の名前はモジュール名と 一致していなければなりません -- 初期化関数の名前が initspam() なら、モジュールはspam という 名前でしか import できません。initspam() は 第一引数を "spam" にして、Py_InitModule() を 呼び出します (このディレクトリにある、最小限の内容が書かれている example.c を手がかりにするとよいでしょう)。 ならわしとして、ファイルはspam.c または spammodule.c という名前にしておきます。 出力ファイル名はリリースモードでは smap.dllspam.pyd、 デバッグモードではsmap_d.dllspam_d.pyd、になるはず です (後者は、システムライブラリ spam.dll と、Python インタフェースとなる自作のモジュールとの混同を避けるために 推奨されています) 。

    さて、やり方は二通りあります:

    1. example.dswexample.dsp をコピーし、 spam.* に名前を変えて、手作業で編集する
    2. 新しくプロジェクトを作成する; 説明は下にあります。

    どちらの場合も、example_nt\example.defspam\spam.def にコピーして、新たにできた spam.def を編集し、二行目に `initspam' が入るように します。 自分で新たなプロジェクトを作成したのなら、ここで spam.def を プロジェクトに追加しておいてください (このファイルはたった二行しか ない目障りなファイルです。.def ファイルを全く無視するという 方法もあり、それには /exprt:initspam を 「プロジェクトのオプション」ダイアログにあるリンク設定のどこかに 手動で追加します)。

  6. 新しくプロジェクトを作成する
    ファイル > 新規作成 > プロジェクト ダイアログ を使って、新たなプロジェクト用ワークスペースを作成します。 Win32 ダイナミックリンクライブラリ を選択し、名前("spam") を入れ、「場所」が先ほど作成した spam ディレクトリ下に (Python ビルドツリーの直下のサブディレクトリで、Include および PC と同じディレクトリになるはずです) あることを 確かめます。「作成」をクリックします。

    プロジェクト > 設定 ダイアログを開きます。 ほんのいくつかですが、設定の変更が必要です。 「構成」ドロップダウンリストに「すべての構成」が設定されているか 確かめてください。C/C++ タブを選び、ポップアップメニュー から「プリプロセッサ」カテゴリを選びます。 以下のテキスト:

    ..\Include,..\PC
    

    を、追加のインクルードディレクトリ とラベルされた エントリボックスに入力します

    次に、「リンカ」タブの「入力」カテゴリを選び、

    ..\PCbuild
    

    を 追加のライブラリディレクトリ と書かれたテキストボックスに 入力します。

    さて、構成ごとに特有の設定をいくつか行う必要があります:

    「構成」 ドロップダウンリストから、Win32 リリース を 選んでください。「リンク」タブをクリックし、「入力」カテゴリを 選んで、「追加の依存ファイル」ボックス内のリストにpythonXY.lib を追加します。

    「構成」 ドロップダウンリストから、Win32 デバッグ に切り替え、 「追加の依存ファイル」ボックス内のリストにpythonXY_d.lib を追加します。 次に C/C++ タブをクリックして、 コード生成 をカテゴリから 選び、 ラインタイムライブラリ に対して マルチスレッド デバッグ DLL を選びます。

    「構成」ドロップダウンリストから Win32 リリース に切り替えなおし ます。 ラインタイムライブラリ に対して マルチスレッド DLL を選びます。

    前の節で述べたspam.def をここで作成しておかねばなりません。 その後、追加 > ファイルをプロジェクトに追加 ダイアログを選びます。「ファイルの種類」を *.* にして、 spam.cspam.def を選び、 OK をクリックします (一つ一つファイルを追加してもかまいません)。

作っているモジュールが新たな型を作成するのなら、 以下の行:

    PyObject_HEAD_INIT(&PyType_Type)

がうまくいかないはずです。そこで:

    PyObject_HEAD_INIT(NULL)

に変更してください。また、以下の行をモジュール初期化関数に加えます:

    MyObject_Type.ob_type = &PyType_Type;

この操作を行う詳しい理由は、 Python FAQ の 第 3 節を参照してください。

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。