文書の過去の版を表示しています。
Boost.Python - Boost Python Library
Boost Python Library は、Python と C++ を連携させるためのフレームワークである。Dave Abrahams の C++ コンパイラだけで、特別なツールを使用することなく、C++ クラスの関数やオブジェクトを Python に素早くシームレスに公開できる。
Windows の Visual Studio での手順
以下は Visual Studio を利用して、Python からインポートできる CPython と Boost.Python で C++ 拡張機能 (C++ extension) を実装する方法の手順である。
前提条件
Python のインストール が済んでいること。
Visual Studio がインストール済みであること。
Boost C++ Libraries がインストール済みであること。
ソリューションと Python プロジェクト (PyHelloBoostPython) の作成
Visual Studio を起動して、「新しいプロジェクトの作成」をクリックする。
言語: Python プラットフォーム: すべてのプラットフォーム プロジェクトの種類: コンソール
を選択して、「Python アプリケーション」をクリックし [次へ] をクリックする。
以下の内容で新しいプロジェクトを構成して [作成] をクリックする。
プロジェクト名: PyHelloBoostPython 場所: <任意のフォルダ> [v] ソリューションとプロジェクトを同じディレクトリに配置する
PyHelloBoostPython ソリューションと PyHelloBoostPython プロジェクトが生成される。
PyHelloBoostPython プロジェクトの Python 環境 を Python 3.8 に設定する。
PyHelloBoostPython プロジェクトの PyHelloBoostPython.py ファイルに以下のコードを貼り付ける。
- PyHelloBoostPython.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from itertools import islice from random import random import timeit from superfastcode_cpython import fast_tanh from superfastcode_boost import boost_tanh COUNT = 500000 # Change this value depending on the speed of your computer NUM_OF_EXEC = 30 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 test(fn, name): # timeit monkey-patching timeit.template = """ def inner(_it, _timer{init}): {setup} _t0 = _timer() for _i in _it: retval = {stmt} _t1 = _timer() return _t1 - _t0, retval """ duration, result = timeit.timeit(lambda: fn(DATA), number=NUM_OF_EXEC) duration = duration / NUM_OF_EXEC print(f'{name} took {duration:.3f} seconds') for d in result: assert -1 <= d <= 1, " incorrect values" def main(): print(f'Running benchmarks with COUNT = {COUNT} x NUM_OF_EXEC = {NUM_OF_EXEC}') test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)') test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ implementation)') test(lambda d: [boost_tanh(x) for x in d], '[boost_tanh(x) for x in d] (Boost.Python C++ implementation)') if __name__ == "__main__": main()
CPython プロジェクト (superfastcode_cpython - Python 用 C++ 拡張機能) の作成
PyHelloBoostPython ソリューションを右クリックして、[追加] - [新しいプロジェクト…] をクリックする。
言語: C++ プラットフォーム: すべてのプラットフォーム プロジェクトの種類: コンソール
を選択して、「空のプロジェクト」をクリックし [次へ] をクリックする。
以下の内容で新しいプロジェクトを構成して [作成] をクリックする。
プロジェクト名: superfastcode_cpython 場所: <任意のフォルダ、もしくは、そのまま>
superfastcode_cpython プロジェクトを右クリックして、[追加] - [新しい項目…] をクリックする。
以下の内容で新しい項目を追加する。
種類: C++ ファイル (.cpp) 名前: cpython_module.cpp 場所: そのまま
superfastcode_cpython プロジェクトを右クリックして、[プロパティ] をクリックする。
初期状態では、構成: アクティブ(Debug)、プラットフォーム: Debug(Win32) になっている。
以下のように、構成: すべての構成、プラットフォーム: すべてのプラットフォーム に変更する。
これにより、Debug、Release、Win32、x64 のすべての組み合わせについての設定を変更する。
CPython プロジェクト (Python 用 C++ 拡張機能) のビルドに必要な設定の概要は以下の通りである。
[構成プロパティ] - [全般] - [構成の種類]: ダイナミック ライブラリ (.dll) [構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子]: .pyd [構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]: Python 3.8 のインクルード ディレクトリ (C:\Python\include など) [構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]: Python 3.8 のライブラリ ディレクトリ (C:\Python\libs など python38.lib の場所を指示)
[構成プロパティ] - [全般] - [構成の種類] を ダイナミック ライブラリ (.dll) に設定する。
[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子] を .pyd に設定する。
[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ] に Python 3.8 のインクルード ディレクトリ を追加する。
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。
%USERPROFILE%\scoop\apps\python\current\include
[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ] に Python 3.8 のライブラリ ディレクトリ を追加する。(python38.lib(Release ビルド時。Debug ビルド時は python38_d.lib が必要。) が存在するディレクトリを指定)
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。
%USERPROFILE%\scoop\apps\python\current\libs
上記のすべての設定が終わったら、プロジェクトのプロパティ ページの [OK] をクリックする。
superfastcode_cpython プロジェクトの cpython_module.cpp ファイルに以下の内容を貼り付ける。
- cpython_module.cpp
#include <Windows.h> #include <cmath> #include <Python.h> 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); } PyObject* tanh_impl_cpy(PyObject*, PyObject* o) { double x = PyFloat_AsDouble(o); double tanh_x = tanh_impl(x); return PyFloat_FromDouble(tanh_x); } static PyMethodDef superfastcode_methods[] = { // The first property is the name exposed to Python, fast_tanh, the second is the C++ // function name that contains the implementation. { "fast_tanh", (PyCFunction)tanh_impl_cpy, METH_O, nullptr }, // Terminate the array with an object containing nulls. { nullptr, nullptr, 0, nullptr } }; static PyModuleDef superfastcode_module = { PyModuleDef_HEAD_INIT, "superfastcode_cpython", // Module name to use with Python import statements "Provides some functions, but faster", // Module description 0, superfastcode_methods // Structure that defines the methods of the module }; PyMODINIT_FUNC PyInit_superfastcode() { return PyModule_Create(&superfastcode_module); }
Boost.Python プロジェクト (superfastcode_boost - Python 用 C++ 拡張機能) の作成
PyHelloBoostPython ソリューションを右クリックして、[追加] - [新しいプロジェクト…] をクリックする。
言語: C++ プラットフォーム: すべてのプラットフォーム プロジェクトの種類: コンソール
を選択して、「空のプロジェクト」をクリックし [次へ] をクリックする。
以下の内容で新しいプロジェクトを構成して [作成] をクリックする。
プロジェクト名: superfastcode_boost 場所: <任意のフォルダ、もしくは、そのまま>
superfastcode_boost プロジェクトを右クリックして、[追加] - [新しい項目…] をクリックする。
以下の内容で新しい項目を追加する。
種類: C++ ファイル (.cpp) 名前: boost_module.cpp 場所: そのまま
superfastcode_boost プロジェクトを右クリックして、[プロパティ] をクリックする。
構成: すべての構成、プラットフォーム: すべてのプラットフォーム について設定する。
これにより、Debug、Release、Win32、x64 のすべての組み合わせについての設定を変更する。
Boost.Python プロジェクト (Python 用 C++ 拡張機能) のビルドに必要な設定の概要は以下の通りである。
[構成プロパティ] - [全般] - [構成の種類]: ダイナミック ライブラリ (.dll) [構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子]: .pyd [構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]: Python 3.8 のインクルード ディレクトリ (C:\Python\include など) [構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]: Python 3.8 のライブラリ ディレクトリ (C:\Python\libs など python38.lib の場所を指示)
[構成プロパティ] - [全般] - [構成の種類] を ダイナミック ライブラリ (.dll) に設定する。
[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子] を .pyd に設定する。
[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ] に Python 3.8 のインクルード ディレクトリ を追加する。
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。
%USERPROFILE%\scoop\apps\python\current\include
[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ] に Python 3.8 のライブラリ ディレクトリ を追加する。(python38.lib(Release ビルド時。Debug ビルド時は python38_d.lib が必要。) が存在するディレクトリを指定)
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。
%USERPROFILE%\scoop\apps\python\current\libs
上記のすべての設定が終わったら、プロジェクトのプロパティ ページの [OK] をクリックする。
superfastcode_boost プロジェクトの boost_module.cpp ファイルに以下の内容を貼り付ける。
- boost_module.cpp
#include <Windows.h> #include <cmath> #include <boost/python.hpp> 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); } BOOST_PYTHON_MODULE(superfastcode_boost) { using namespace boost::python; def("boost_tanh", tanh_impl); }
ソリューションの設定
ソリューション エクスプローラー より PyHelloBoostPython ソリューションを右クリックして、[構成マネージャー…]をクリックする。
アクティブ ソリューション構成: Debug に変更して、以下のプロジェクトが Release ビルド、x64 プラットフォーム でビルドされるように設定する。(標準では Python の python38.lib (Release 版) のみのため)
プロジェクト | 構成 | プラットフォーム |
---|---|---|
superfastcode_boost | Release | x64 |
superfastcode_cpython | Release | x64 |
アクティブ ソリューション構成: Release に変更して、以下のプロジェクトが Release ビルド、x64 プラットフォーム でビルドされるように設定する。(標準では Python の python38.lib (Release 版) のみのため)
プロジェクト | 構成 | プラットフォーム |
---|---|---|
superfastcode_boost | Release | x64 |
superfastcode_cpython | Release | x64 |
ソリューション内の Python プロジェクトで C++ 拡張機能 プロジェクトを参照する
superfastcode_cpython、および、superfastcode_boost プロジェクトの Python 用 C++ 拡張機能は、同一ソリューション内であってもそのままでは Python から import できない。
PyHelloBoostPython プロジェクトの[参照]を右クリックして、[参照の追加…]を右クリックする。
superfastcode_cpython、および、superfastcode_boost プロジェクトのチェックボックスをオンにして [OK] をクリックする。
以下のように PyHelloBoostPython プロジェクトの参照に C++ 拡張機能 プロジェクトが追加されて、検索パス (x64\Relase) にビルド出力の *.pyd ファイルが配置されるので Python プロジェクトから import することが可能になる。