Python 用 C++ 拡張機能の作成Creating a C++ extension for Python

Python インタープリターの機能を拡張するため、およびオペレーティング システムの低レベル機能にアクセスするためには、C++ (または C) で記述されたモジュールがよく使われます。Modules written in C++ (or C) are commonly used to extend the capabilities of a Python interpreter as well as to enable access to low-level operating system capabilities. モジュールの主要な種類は次の 3 つです。There are three primary types of modules:

  • アクセラレータ モジュール: Python はインタープリター言語であるため、コードの特定の部分を C++ で書くことによってパフォーマンスを向上させることができます。Accelerator modules: because Python is an interpreted language, certain pieces of code can be written in C++ for higher performance.
  • ラッパー モジュール: ラッパーは、既存の C/C++ インターフェイスを Python コードに公開します。また、Python から使いやすい、より "Python らしい" API を公開します。Wrapper modules: wrappers expose existing C/C++ interfaces to Python code or expose a more "Pythonic" API that's easy to use from Python.
  • 低レベル システム アクセス モジュール: CPython ランタイム、オペレーティング システム、または基盤ハードウェアの低レベル機能にアクセスするために作成します。Low-level system access modules: created to access lower-level features of the CPython runtime, the operating system, or the underlying hardware.

このトピックでは、双曲正接を計算する CPython 用の C++ 拡張モジュールを作成し、Python コードからそれを呼び出す手順について説明します。This topic walks through building a C++ extension module for CPython that computes a hyperbolic tangent and calls it from Python code. Python では最初にルーチンを実装して、C++ で同じルーチンを実装した場合のパフォーマンス向上を示します。The routine is implemented first in Python to demonstrate the performance gain of implementing the same routine in C++.

ここでは、Python のドキュメントで説明されている CPython の標準拡張機能のためのアプローチを使います。The approach taken here is that for standard CPython extensions as described in the Python documentation. この方法と他の方法の比較については、このトピックの最後にある「別の方法」で説明します。A comparison between this and other means is described under alternative approaches at the end of this topic.

必須コンポーネントPrerequisites

  • C++ によるデスクトップ開発Python 開発ワークロードの両方を備えた Visual Studio 2017 が既定のオプションでインストールされます。Visual Studio 2017 with both the Desktop Development with C++ and Python Development workloads installed with default options.
  • Python 開発ワークロードでは、[Python ネイティブ開発ツール] のチェック ボックスもオンにし、それによりこのトピックで説明するほとんどのオプションが設定されますIn the Python Development workload, also check the box on the right for Python native development tools, which sets up most of the options described in this topic. (このオプションには、C++ のワークロードも自動的に含まれます)。(This option also includes the C++ workload automatically.)

[Python ネイティブ開発ツール] オプションの選択

  • データ サイエンスと分析アプリケーション ワークロードをインストールすることでも、Python と Python ネイティブ開発ツール オプションが既定で含まれます。Installing the Data science and analytical applications workload also includes Python and the Python native development tools option by default.

他のバージョンの Visual Studio の使用など、詳細については「Visual Studio 用の Python サポートのインストール」を参照してください。For more information, see Installing Python Support for Visual Studio, including using other versions of Visual Studio. Python を別にインストールする場合は、インストーラーで [詳細オプション][Download debugging symbols (デバッグ シンボルのダウンロード)][Download debug binaries (デバッグ バイナリのダウンロード)] を必ず選んでください。If you install Python separately, be sure to select Download debugging symbols and Download debug binaries under Advanced Options in the installer. このオプションを選択すると、デバッグ ビルドを行う場合に、必要なデバッグ ライブラリを確実に使用できます。This option ensures that you have the necessary debug libraries available if you choose to do a debug build.

Python アプリケーションを作成するCreate the Python application

  1. Visual Studio で [ファイル]、[新規]、[プロジェクト] の順に選択して、新しい Python プロジェクトを作成します。Create a new Python project in Visual Studio by selecting File > New > Project. "Python" を検索し、Python アプリケーション テンプレートを選択し、適切な名前と場所を指定し、[OK] を選択します。Search for "Python", select the Python Application template, give it a suitable name and location, and select OK.

  2. プロジェクトの .py ファイルに、双曲正接の計算をベンチマークする次のコードを貼り付けます (簡単に比較できるよう、数値演算ライブラリを使わずに実装されています)。In the project's .py file, paste the following code that benchmarks the computation of a hyperbolic tangent (implemented without using the math library for easier comparison). 自由に手動でコードを入力し、Python の編集機能を体験してください。Feel free to enter the code manually to experience some of the Python editing features.

    from itertools import islice
    from random import random
    from time import perf_counter
    
    COUNT = 500000  # Change this value depending on the speed of your computer
    DATA = list(islice(iter(lambda: (random() - 0.5) * 3.0, None), COUNT))
    
    e = 2.7182818284590452353602874713527
    
    def sinh(x):
        return (1 - (e ** (-2 * x))) / (2 * (e ** -x))
    
    def cosh(x):
        return (1 + (e ** (-2 * x))) / (2 * (e ** -x))
    
    def tanh(x):
        tanh_x = sinh(x) / cosh(x)
        return tanh_x
    
    def sequence_tanh(data):
        '''Applies the hyperbolic tangent function to map all values in
        the sequence to a value between -1.0 and 1.0.
        '''
        result = []
        for x in data:
            result.append(tanh(x))
        return result
    
    def test(fn, name):
        start = perf_counter()
        result = fn(DATA)
        duration = perf_counter() - start
        print('{} took {:.3f} seconds\n\n'.format(name, duration))
    
        for d in result:
            assert -1 <= d <=1, " incorrect values"
    
    if __name__ == "__main__":
        print('Running benchmarks with COUNT = {}'.format(COUNT))
        test(sequence_tanh, 'sequence_tanh')
    
        test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d]')
    
  3. [デバッグ] > [デバッグなしで開始] (Ctrl + F5 キー) を使ってプログラムを実行し、結果を確認します。Run the program using Debug > Start without Debugging (Ctrl+F5) to see the results. COUNT 変数を調整して、ベンチマークの実行にかかる時間を変更することができます。You can adjust the COUNT variable to change how long the benchmarks take to run. このチュートリアルの目的は、各ベンチマークの所要時間を約 2 秒にするように、カウントを設定することです。For the purposes of this walkthrough, set the count so that each benchmark takes around two seconds.

C++ のコア プロジェクトを作成するCreate the core C++ project

  1. ソリューション エクスプローラーでソリューション名を右クリックし、[追加] > [新しいプロジェクト...] を選びます。同じ Visual Studio ソリューションに、Python と C++ 両方のプロジェクトを含めることができます。Right-click the solution in Solution Explorer and select Add > New Project.... A Visual Studio solution can contain both Python and C++ projects together.

  2. "C++" を検索し、[空のプロジェクト] を選び、名前 (TanhBenchmark など) を指定して、[OK] を選びます。Search on "C++", select Empty project, specify a name (such as TanhBenchmark), and select OK. 注: Visual Studio 2017 で Python ネイティブ開発ツールをインストールした場合は、Python 拡張モジュールから始めることができます。このテンプレートには、ここで説明するものの多くが既に配置されています。Note: if you've installed the Python native development tools with Visual Studio 2017, you can start with the Python Extension Module template, which has much of what's described here already in place. ただし、このチュートリアルでは、拡張モジュールの作成手順を実際に示すため、空のプロジェクトから始めます。For this walkthrough, though, starting with an empty project demonstrates building the extension module step by step.

  3. [ソース ファイル] ノードを右クリックし、[追加] > [新しい項目...] を選び、[C++ ファイル] を選んで名前 (module.cpp など) を指定してから [OK] を選び、新しいプロジェクトに C++ ファイルを作成します。Create a C++ file in the new project by right-clicking the Source Files node, then select Add > New Item...", select C++ File, give it a name (like module.cpp), and select OK. このステップは、次のステップで C++ のプロパティ ページを有効にするために必要です。This step is necessary to turn on the C++ property pages in the next steps.

  4. 新しいプロジェクトを右クリックして [プロパティ] を選び、表示される [プロパティ ページ] ダイアログ ボックスの上部で、[構成][すべての構成] に設定します。Right-click the new project and select Properties, then at the top of the Property Pages dialog that appears, set Configuration to All Configurations.

  5. 以下に示すように、特定のプロパティを設定し、[OK] を選択します。Set the specific properties as described below, then select OK.

    タブTab プロパティProperty Value
    全般General [全般] > [ターゲット名]General > Target Name Python が認識するモジュールの名前と完全に一致するようにこのフィールドを設定します。Set this field to exactly match the name of the module as Python sees it.
    [全般] > [ターゲットの拡張子]General > Target Extension .pyd.pyd
    [プロジェクトの既定値] > [構成の種類]Project Defaults > Configuration Type ダイナミック ライブラリ (.dll)Dynamic Library (.dll)
    [C/C++] > [全般]C/C++ > General 追加のインクルード ディレクトリAdditional Include Directories インストールに合わせて Python の include フォルダーを追加します (例: c:\Python36\include)Add the Python include folder as appropriate for your installation, for example, c:\Python36\include
    [C/C++] > [プリプロセッサ]C/C++ > Preprocessor プリプロセッサの定義Preprocessor Definitions 文字列の先頭に Py_LIMITED_API; を追加し、Python から呼び出すことができる一部の関数を制限し、Python の異なるバージョン間でのコードの移植性を高くします。Add Py_LIMITED_API; to the beginning of the string, which restricts some of the functions you can call from Python and makes the code more portable between different versions of Python.
    [C/C++] > [コード生成]C/C++ > Code Generation ランタイム ライブラリRuntime Library マルチスレッド DLL (/MD) (下記の「警告」を参照)Multi-threaded DLL (/MD) (see Warning below)
    [リンカー] > [全般]Linker > General 追加のライブラリ ディレクトリAdditional Library Directories インストールに合わせて、.lib ファイルが含まれる Python の libs フォルダーを追加します (例: c:\Python36\libs)Add the Python libs folder containing .lib files as appropriate for your installation, for example, c:\Python36\libs. (.py ファイルが含まれる Lib フォルダーではなく.lib ファイルが含まれる libs フォルダーを必ず指定してください)。(Be sure to point to the libs folder that contains .lib files, and not the Lib folder that contains .py files.)

    ヒント

    [C/C++] タブが表示されない場合は、C/C++ ソース ファイルとして識別されるファイルがプロジェクトに含まれないためです。If you don't see the C/C++ tab, it's because the project doesn't contain any files that it identifies as C/C++ source files. このような条件は、.c または .cpp 拡張子を付けずにソース ファイルを作成すると発生する可能性があります。This condition can occur if you create a source file without a .c or .cpp extension. たとえば、前の [新しい項目] ダイアログで、つい module.cpp ではなく module.coo と入力してしまった場合、Visual Studio はファイルを作成しますが、ファイルの種類を "C/C++ コード" に設定しないので、C/C++ のプロパティ タブがアクティブになりません。この識別の誤処理は、ファイル名を .cpp に変更しても解決しません。For example, if you accidentally entered module.coo instead of module.cpp in the new item dialog earlier, then Visual Studio creates the file but doesn't set the file type to "C/C+ Code," which is what activates the C/C++ properties tab. This misidentification remains the case even if you rename the file with .cpp. ファイルの種類を正しく設定するには、ソリューション エクスプローラーでファイルを右クリックして [プロパティ] を選び、[ファイルの種類][C/C++ コード] に設定します。To set the file type properly, right-click the file in Solution Explorer, select Properties, then set File Type to C/C++ Code.

    警告

    デバッグ構成であっても、[C/C++] > [コード生成] > [ランタイム ライブラリ] オプションを [マルチスレッド デバッグ DLL (/MDd)] に設定しないでください。Don't set the C/C++ > Code Generation > Runtime Library option to "Multi-threaded Debug DLL (/MDd)" even for a Debug configuration. 非デバッグ Python バイナリのビルドに使われている [マルチスレッド DLL (/MD)] ランタイムを選択してください。Select the "Multi-threaded DLL (/MD)" runtime because that's what the non-debug Python binaries are built with. /MDd オプションを設定すると、DLL のデバッグ構成をビルドするときに、C1189: Py_LIMITED_API は Py_DEBUG、Py_TRACE_REFS、Py_REF_DEBUG と互換性がありませんというエラーが表示されます。If you happen to set the /MDd option, you see error C1189: Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG when building a Debug configuration of your DLL. さらに、ビルド エラーを避けるために Py_LIMITED_API を削除すると、モジュールをインポートしようとしたときに Python がクラッシュしますFurthermore, if you remove Py_LIMITED_API to avoid the build error, Python crashes when attempting to import the module. (後で説明しますが、クラッシュは DLL のPyModule_Create の呼び出し内で発生し、出力メッセージは "Fatal Python error: PyThreadState_Get: no current thread (Python 致命的エラー: PyThreadState_Get: 現在のスレッドがありません)" です)。(The crash happens within the DLL's call to PyModule_Create as described later, with the output message of Fatal Python error: PyThreadState_Get: no current thread.)

    /MDd オプションは Python デバッグ バイナリ (python_d.exe など) のビルドに使われますが、拡張 DLL に対して選ぶと、やはり Py_LIMITED_API のビルド エラーになることに注意してください。Note that the /MDd option is what's used to build the Python debug binaries (such as python_d.exe), but selecting it for an extension DLL still causes the build error with Py_LIMITED_API.

  6. C++ プロジェクトを右クリックし、[ビルド] を選んで構成をテストします (デバッグとリリースの両方)。Right-click the C++ project and select Build to test your configurations (both Debug and Release). .pyd ファイルは、C++ のプロジェクト フォルダー自体ではなく、Debug および Release の下の solution フォルダーにあります。The .pyd files are located in the solution folder under Debug and Release, not the C++ project folder itself.

  7. C++ プロジェクトのメインの .cpp ファイルに、次のコードを追加します。Add the following code to the C++ project's main .cpp file:

    #include <Windows.h>
    #include <cmath>    
    
    const double e = 2.7182818284590452353602874713527;
    
    double sinh_impl(double x) {
        return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
    }
    
    double cosh_impl(double x) {
        return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
    }
    
    double tanh_impl(double x) {
        return sinh_impl(x) / cosh_impl(x);
    }
    
  8. C++ プロジェクトを再度ビルドし、コードが正しいことを確認します。Build the C++ project again to confirm that your code is correct.

C++ プロジェクトを Python の拡張機能に変換するConvert the C++ project to an extension for Python

C++ DLL を Python の拡張機能にするには、Python の型と対話するようにエクスポートしたメソッドを変更する必要があります。To make the C++ DLL into an extension for Python, you need to modify the exported methods to interact with Python types. その後、モジュールのメソッドの定義と共に、モジュールをエクスポートする関数を追加する必要があります。Then you need to add a function that exports the module, along with definitions of the module's methods. これらの背景については、python.org で「Python/C API Reference Manual」(Python/C API リファレンス マニュアル) および特に「Module Objects」(モジュールのオブジェクト) をご覧ください(右上のドロップダウン コントロールで Python のバージョンを選んでください)。For background on what's shown here, refer to the Python/C API Reference Manual and especially Module Objects on python.org. (Remember to select your version of Python from the drop-down control on the upper right.)

  1. C++ ファイルの先頭に Python.h を含めます。In the C++ file, include Python.h at the top:

    #include <Python.h>
    
  2. Python の型を受け付けて戻すように、tanh_impl メソッドを変更します。Modify the tanh_impl method to accept and return Python types:

    PyObject* tanh_impl(PyObject *, PyObject* o) {
        double x = PyFloat_AsDouble(o);
        double tanh_x = sinh_impl(x) / cosh_impl(x);
        return PyFloat_FromDouble(tanh_x);
    }
    
  3. Python に対して C++ の tanh 関数を提示する方法を定義する構造体を追加します。Add a structure that defines how the C++ tanh function is presented to Python:

    static PyMethodDef superfastcode_methods[] = {
        // The first property is the name exposed to python, the second is the C++ function name        
        { "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },
    
        // Terminate the array with an object containing nulls.
        { nullptr, nullptr, 0, nullptr }
    };
    
  4. Python が認識するモジュールを定義する構造体を追加します。Add a structure that defines the module as Python sees it:

    static PyModuleDef superfastcode_module = {
        PyModuleDef_HEAD_INIT,
        "superfastcode",                        // Module name
        "Provides some functions, but faster",  // Module description
        0,
        superfastcode_methods                   // Structure that defines the methods
    };
    
  5. モジュールを読み込むときに Python が呼び出すメソッドを追加します。PyInit_<module-name> という名前にする必要があります。<module_name> は、C++ プロジェクトの [全般] > [ターゲット名] プロパティと正確に一致します (つまり、プロジェクトによってビルドされる .pyd のファイル名と一致します)。Add a method that Python calls when it loads the module, which must be named PyInit_<module-name>, where <module_name> exactly matches the C++ Project's General > Target Name property (that is, it matches the filename of the .pyd built by the project).

    PyMODINIT_FUNC PyInit_superfastcode() {    
        return PyModule_Create(&superfastcode_module);
    }
    
  6. もう一度 C++ プロジェクトをビルドして、コードを検証します。Build the C++ project again to verify your code.

コードをテストして結果を比較するTest the code and compare the results

Python 拡張機能の構造の DLL ができたので、Python プロジェクトからそれを参照し、モジュールをインポートして、そのメソッドを使うことができます。Now that you have the DLL structured as a Python extension, you can refer to it from the Python project, import the module, and use its methods.

Python で DLL を使用できるようするMake the DLL available to Python

Python で DLL を使えるようにするには 2 つの方法があります。There are two ways to make the DLL available to Python.

第 1 の方法は、Python プロジェクトと C++ プロジェクトが同じ Visual Studio ソリューション内にある場合に有効で、Python プロジェクトから C++ プロジェクトへの参照を追加します。First, you can add a reference from the Python project to the C++ project, provided that they're in the same Visual Studio solution:

  1. ソリューション エクスプローラーで、Python プロジェクト内の [参照設定] ノードを右クリックし、[参照の追加] をクリックします。In Solution Explorer, right-click the References node in your Python project and select Add Reference. 表示されるダイアログの [プロジェクト] タブで、superfastcode プロジェクト (または使用している名前) を選択し、[OK] を選択します。In the dialog that appears, select the Projects tab, select the superfastcode project (or whatever name you're using), and then OK.

第 2 の方法は、グローバル Python 環境にモジュールをインストールし、他の Python プロジェクトでも使えるようにします。Second, you can install the module in the global Python environment, making it available to other Python projects as well. そのためには、通常、その環境に合わせて IntelliSense 入力候補データベースを更新する必要があります。Doing so typically requires that you refresh the IntelliSense completion database for that environment. 環境からモジュールを削除するときも、更新する必要があります。Refreshing is also necessary when removing the module from the environment.

  1. Visual Studio 2017 を使っている場合は、Visual Studio インストーラーを実行して [変更] を選び、[個別のコンポーネント] > [コンパイラ、ビルド ツール、およびランタイム] > [Visual C++ 2015.3 v140 ツールセット] を選びます。If you're using Visual Studio 2017, run the Visual Studio installer, select Modify, select Individual Components > Compilers, build tools, and runtimes > Visual C++ 2015.3 v140 toolset. この手順が必要な理由は、Python (for Windows) 自体が Visual Studio 2015 (バージョン 14.0) でビルドされ、ここで説明する方法で拡張機能をビルドするときはこれらのツールが使えることが想定されるためです。This step is necessary because Python (for Windows) is itself built with Visual Studio 2015 (version 14.0) and expects that those tools are available when building an extension through the method described here.

  2. プロジェクトを右クリックし、[追加] > [新しい項目] を選択して、C++ プロジェクトに setup.py という名前のファイルを作成します。次に、"C++ File (.cpp)" を選択し、ファイルに setup.py という名前を付け、[OK] を選択します (.py 拡張子を使用してファイルに名前を付けることで、C++ ファイル テンプレートを使用していても、Visual Studio でそのファイルが Python として認識されるようにします)。Create a file named setup.py in your C++ project by right-clicking the project and selecting Add > New Item.... Then select "C++ File (.cpp)", name the file setup.py, and selecting OK (naming the file with the .py extension makes Visual Studio recognize it as Python despite using the C++ file template). ファイルがエディターに表示されたら、そこに次のコードを貼り付けます。When the file appears in the editor, paste the following code into it:

    from distutils.core import setup, Extension, DEBUG
    
    sfc_module = Extension('superfastcode', sources = ['module.cpp'])
    
    setup(name = 'superfastcode', version = '1.0',
        description = 'Python Package with superfastcode C++ Extension',
        ext_modules = [sfc_module]
        )
    

    このスクリプトについては、「Building C and C++ Extensions」(C と C++ の拡張機能のビルド) (python.org) をご覧ください。See Building C and C++ Extensions (python.org) for documentation on this script.

  3. setup.py コードをコマンド ラインから使用すると、Visual Studio 2015 C++ ツールセット使って拡張機能をビルドするように Python に指示します。The setup.py code instructs Python to build the extension using the Visual Studio 2015 C++ toolset when used from the command line. 管理者特権でコマンド プロンプトを開き、C++ プロジェクト (および setup.py) を含むフォルダーに移動して、次のコマンドを入力します。Open an elevated command prompt, navigate to the folder containing the C++ project (and setup.py), and enter the following command:

    pip install .
    

Python から DLL を呼び出すCall the DLL from Python

上記のいずれかの方法が完了したら、fast_tanh 関数を呼び出し、そのパフォーマンスを Python の実装と比較できるようになります。After you've completed either of the methods above, you can now call the fast_tanh function and compare its performance to the Python implementation:

  1. 次の行を .py ファイルに追加して、DLL からエクスポートされた fast_tanh メソッドを呼び出してその出力を表示します。Add the following lines in your .py file to call the fast_tanh method exported from the DLL and display its output. from s ステートメントを手入力する場合は、入力候補一覧に superfastcode が表示され、「import」と入力すると fast_tanh メソッドが表示されます。If you type the from s statement manually, you'll see superfastcode come up in the completion list, and after typing import the fast_tanh method appears.

    from superfastcode import fast_tanh    
    test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d]')
    
  2. Python プログラムを実行すると、Python の実装より C++ ルーチンの方が 5 から 20 倍速いことがわかります。Run the Python program and see that the C++ routine runs 5 to 20 times faster than the Python implementation. 違いがより顕著になるように、もう一度、COUNT 変数を増やしてみます。Again, try increasing the COUNT variable so that the differences are more pronounced. また、C++ モジュールのリリース ビルドの実行は、デバッグ ビルドよりも高速になることに注意してください。これは、デバッグ ビルドが十分に最適化されず、さまざまなエラー チェックが含まれるためです。Also note that a Release build of the C++ module runs faster than a Debug build because the Debug build is less optimized and contains various error checks. これらの構成間を自由に切り替えて比較することができます。Feel free to switch between those configurations for comparison.

C++ コードをデバッグするDebug the C++ code

Visual Studio では、Python と C++ コードを一緒にデバッグすることをサポートしています。Visual Studio supports debugging Python and C++ code together.

  1. ソリューション エクスプローラーで Python プロジェクトを右クリックして、[プロパティ][デバッグ] タブを選び、[デバッグ] > [ネイティブ コードのデバッグを有効にする] オプションをオンにします。Right-click the Python project in Solution Explorer, select Properties, select the Debug tab, and then select the Debug > Enable native code debugging option.

    ヒント

    ネイティブ コードのデバッグを有効にすると、プログラムが通常の [続行するには、任意のキーを押してください] で一時停止せずに完了した場合に、Python の出力ウィンドウがすぐに消えることがあります。When you enable native code debugging, the Python output window may disappear immediately when the program has completed without giving you the usual "Press any key to continue..." pause. 強制的に一時停止するには、ネイティブ コードのデバッグを有効にするときに、[デバッグ] タブの [実行] > [インタープリターの引数] フィールドに、-i オプションを追加します。To force a pause, add the -i option to the Run > Interpreter Arguments field on the Debug tab when you enable native code debugging. この引数を使用すると、Python インタープリターはコード終了後に対話モードになり、この時点でユーザーが Ctrl + Z キー、Enter キーの順に押して終了するのを待機します。This argument puts the Python interpreter into interactive mode after the code finishes, at which point it waits for you to press Ctrl+Z, Enter to exit. (または、Python コードを変更してもよい場合は、プログラムの最後に import os および os.system("pause") ステートメントを追加します。(Alternately, if you don't mind modifying your Python code, you can add import os and os.system("pause") statements at the end of your program. このコードで、元の一時停止プロンプトが複製されます)。This code duplicates the original pause prompt.)

  2. [ファイル] > [保存] を選択して、プロパティの変更を保存します。Select File > Save to save the property changes.

  3. Visual Studio ツールバーで、ビルド構成を [デバッグ] に設定します。Set the build configuration to Debug in the Visual Studio toolbar.

    ビルド構成を [デバッグ] に設定する

  4. 通常デバッガーでコードを実行するとより時間がかかるため、.py ファイルの COUNT 変数を約 5 倍小さい値 (たとえば、500000 から 100000) に変更できます。Because code generally takes longer to run in the debugger, you may want to change the COUNT variable in your .py file to a value that's about 5 times smaller (for example, change it from 500000 to 100000).

  5. C++ コードで tanh_impl メソッドの先頭行にブレークポイントを設定して、(F5 を押すか、[デバッグ] > [デバッグの開始] の順に選択して) デバッガーを開始します。In your C++ code, set a breakpoint on the first line of the tanh_impl method, then start the debugger (F5 or Debug > Start Debugging). そのコードが呼び出されるとデバッガーが停止します。The debugger stops when that code is called. ブレークポイントがヒットしない場合は、構成が [デバッグ] に設定されていること、およびプロジェクトを保存していること (これはデバッガーの開始時に自動的に行われません) を確認します。If the breakpoint is not hit, check that the configuration is set to Debug and that you've saved the project (which does not happen automatically when starting the debugger).

    C++ コードのブレークポイントでの停止

  6. この時点で、C++ コードをステップ実行したり、変数を調べたりできます。At this point you can step through the C++ code, examine variables, and so on. これらの機能の詳細については、「Python と C++ の同時デバッグ」をご覧ください。These features are detailed in Debugging C++ and Python Together.

別の方法Alternative approaches

次の表で説明するように、Python の拡張機能を作成するにはさまざまな方法があります。There are a variety of means to create Python extensions as described in the table below. CPython の最初のエントリは、このトピックで既に説明したものです。The first entry for CPython is what's been discussed in this topic already.

方法Approach 時期Vintage 代表的ユーザーRepresentative User(s) 長所Pro(s) 短所Con(s)
CPython 用の C/C++ 拡張モジュールC/C++ extension modules for CPython 19911991 標準ライブラリStandard Library 広範なドキュメントとチュートリアルExtensive documentation and tutorials. 総合的な制御。Total control. コンパイル、移植性、参照の管理。Compilation, portability, reference management. C についての深い知識。High C knowledge.
SWIGSWIG 19961996 crfsuitecrfsuite 多くの言語のバインドを一度に生成。Generate bindings for many languages at once. Python が唯一のターゲットである場合、過剰なオーバーヘッド。Excessive overhead if Python is the only target.
ctypesctypes 20032003 oscryptooscrypto コンパイルがなく、広く利用可能。No compilation, wide availability. C 構造体のアクセスや変更が煩雑で、エラーを起こしやすい。Accessing and mutating C structures cumbersome and error prone.
CythonCython 20072007 geventkivygevent, kivy Python に似ている。Python-like. 非常に完成されている。Highly mature. 高パフォーマンス。High performance. コンパイル、新しい構文、ツールチェーン。Compilation, new syntax and toolchain.
cfficffi 20132013 cryptographypypycryptography, pypy 容易な統合、PyPy との互換性。Ease of integration, PyPy compatibility. 新しく、未完成な部分がある。New, less mature.