はじめに
- 本記事では、Boostライブラリを利用し、C++からPythonを呼び出す方法をまとめる
- x86 ビルド(32bit)での環境構築に限定し、x64 ビルド(64bit)の解説は行わない
- 64bit版は、こちらの記事へ。
- 32bit版での環境構築の際は、64bit版Python, Anacondaを全て削除することをおすすめします。(ハマるポイントが少なくなります)
何を実現したいのか?
- VisualStudioのC++プロジェクトから、Pythonクラスを利用したい
- 速度の求められる処理をC++で実行し、一部の複雑な処理はPythonを利用したい
- 32bitマシンを制御する必要がある(シーケンサ、マイコン、ロボットなど)
32bit 環境のセットアップ
- 環境構築の流れは64bitと同じだが、少々クセがあるため以下で説明する。
1. Pythonインストール
- Python本家から、Python 3.8
(32bit)
をインストールする- Anaconda は使用しない方が良い。
- Anacondaではうまくいかないとのコメントがありました。( こちらのリンクを押し、一番下までスクロール)
- 複数バージョンのPythonを入れると設定がめんどくさくなります。PC内に、32bit版Pythonのみが存在する状態にしておいた方が良いです。
- Anaconda は使用しない方が良い。
2. Boostセットアップ
-
Boostをダウンロードする(筆者は Boost 1.76.0)
- 本記事ではCドライブ直下にダウンロード
-
解凍したBoostのファイル中で、
bootstrap.bat
を実行するcd C:\boost_1_76_0 #解凍したフォルダパスへGO C:\boost_1_76_0>bootstrap.bat
-
実行後、
project-config.jam
というフォルダが出来上がっているので、このファイルを変更する- これが、Boostのビルドオプションの設定ファイル
project-config.jam# Boost.Build Configuration # Automatically generated by bootstrap.bat import option ; using msvc ; option.set keep-going : false ; using python : 3.8 : C:/Users/Tanaka.Taro/AppData/Local/Programs/Python/Python38-32 : C:/Users/Tanaka.Taro/AppData/Local/Programs/Python/Python38-32/include : C:/Users/Tanaka.Taro/AppData/Local/Programs/Python/Python38-32/libs : ;
-
ポイント:自分の環境に合わせ、下記のように設定する
using python : [Pythonのバージョン] : [Pythonのルートディレクトリ] : [Pythonのルートディレクトリ]/include : [Pythonのルートディレクトリ]/libs : ;
- ↑上記のコードの空白文字(スペース)は省略しないこと!(
libs : ;
などの箇所です)
-
project-config.jam の設定後、b2.exeを実行する
- コマンドプロントで下記のコマンドを実行
b2.exe toolset=msvc-14.2 link=static,shared runtime-link=static,shared address-model=32 -j12 install --build-dir=C:\boost_1_76_0\build\x86 --includedir=C:\boost_1_76_0\include --libdir=C:\boost_1_76_0\stage\lib\x86
- コマンドプロントで下記のコマンドを実行
-
b2.exe コンパイルオプションの解説
- toolset= "コンパイラを指定"
- runtime-link="Visual Studioで使用する際のBoostライブラリのリンク形式"
- Boostライブラリ使用時に下記の違いがある
- runtime-link=static : Visual Studioで(MT or MTd)を指定する
- runtime-link=shared : Visual Studioで(MD or MDd)を指定する
- 注意: sharedの場合、実行時に.libと同名のdllを置かなければならない
- Boostライブラリ使用時に下記の違いがある
- address-model="ビット数: 32 or 64 を指定"
- -j12: "ビルド時の並列スレッド数。(数値を大きくするほどコンパイルが早くなるが、いずれ頭打ちになる)
- --build-dir="ビルド後のBoost実行ファイルが生成される場所"
- --includedir="ビルド後のBoostライブラリのヘッダファイルが生成される場所"
- --libdir="ビルド後のBoostライブラリのライブラリファイルが生成される場所"
- コマンド中に
--with-python
オプションはつけない(すべてのパッケージをインストールする)- --with-python: "Boost提供ライブラリのうち、Pythonのみ利用しますよ。という意味"
-
ポイント
-
msvc-14.2
の数値は、自身のVisualStudioのバージョンによって変えなければならない- 確認方法
- VisualStudioを開く > プロジェクト > プロパティ > プラットフォームツールセット
- 確認方法
- b2.exeの実行オプションは、こちらの記事 にまとまっているので、一読すること
-
3. Visual Studio のセットアップ
- Boostのビルドが完了したら、次はVisualStudioでBoostPythonを利用するための設定を行う
- 今回は32bitビルドなので、 ビルドプラットフォームを
x86
にすること。- プロジェクトのプロパティを設定する
- C/C++ --> 全般 --> 追加のインクルードディレクトリ
- C:\boost_1_76_0\include\boost-1_76
- [Pythonのルートディレクトリ]/include
- リンカー --> 全般 --> 追加のライブラリディレクトリ
- C:\boost_1_76_0\stage\lib\x86
- [Pythonのルートディレクトリ]/libs
- C/C++ --> 全般 --> 追加のインクルードディレクトリ
- プロジェクトのプロパティを設定する
PCの環境変数の設定
- 筆者の環境では特にいじる必要がなかったが、もしうまくいかない場合は環境変数を確認するとよいかも
- PCに複数のPythonバージョンがインストールされていたり、Anacondaを利用している場合、環境変数あたりで苦戦するはず。
C++からPythonを利用する
Boost Python 使用時の作法
- プログラムを作成する際に気を付ける点をまとめる
-
プログラムの初めに
Py_Initialize();
を、プログラムの終わりに(必須ではない)をつけることPy_Finalize();
-
Boost::numpy を使用する際は、np::initialize(); もつけること
-
プログラム全体を try-catchで囲み、キャッチした例外をPrint()できるようにすること
main.pyint main() { //名前空間 namespace py = boost::python; try { //初期化 Py_Initialize(); // Do something with Python ! // } catch (py::error_already_set& e) { // Pythonの例外を標準出力にPrintします PyErr_Print(); } Py_Finalize(); }
-
※ 補足
- Python から 返り値で渡されたnumpy配列の値をC++で取得しようとすると変な値になった。要確認。
- BoostPythonで実行中、Pythonのカレントディレクトリは、C++ソースファイルの場所になることに注意。(ファイルパスが通らない場合確認のこと)
-