C++ で Python を実行 on Visual Studio 2017


背景

お仕事()でC++でPythonを実行したい、しなくてはいけない状況になりました。
その際に環境構築にかなり手間取ったので一度まとめたいと思います。
いくつかインストールします。
時間もかかります。

開発環境

・ノートパソコン
・OS:window 10 64 bit
・CPU:へっぽこ
・GPU:なし
・Visual Studio 2017
・C++
・Python 3.7.4

インストール内容

・Visual Studio 2017
・Python 3.7.4
・boost 1.70.0

インストール:Visual Studio 2017

下のURLにいき、「Download Community 2017」をダウンロードします。
こちらは個人等であれば無料で使えます。
あとMicrosoftのアカウントを作成しておくことをお勧めします。
1か月ほど使用しているとアカウントを作ってログインしないとつかわせないぞ~、と言われますよ(恐怖)。

URL
https://docs.microsoft.com/ja-jp/visualstudio/releasenotes/vs2017-relnotes

次にインストールします。
左側の「C++によるデスクトップ開発」と「右側のWINDOWS 10 SDK」のそれぞれにチェックを入れます。
Pythonはここではいれません
今回は純正Pythonを入れます。 
Visual studio 2017によってPython(またはanaconda)をいれてもいいんですが、
個人的にVisual studio 2017にPythonを依存させてしまうのが怖いので、
互いに独立するように環境を構築します。

下のようにインストールが始まります。

インストール:Python 3.7.4

Pythonのインストール方法はたくさんのサイトで確認できますが、確認用に載せます。

URL
https://www.python.org/downloads/release/python-374/

URLの下にスクロールするとFilesがあります。
OSがwindosn 64bitなのでwindos x86-64 executable installerをダウンロードします。

Add Python 3.7 to PATH にチェックを入れて、自身のPC内の環境変数パスを通します。

インストール:boost 1.70.0

以下のURLからダウンロードします。

URL
https://www.boost.org/users/history/version_1_70_0.html

boostはC++とPythonをつなげるライブラリの要素もあります。
最新バージョンもありますが、1.70.0は以前にも使用できることを確認できているので、今回はこちらを指定しました。

ダウンロードして、展開し、Cドライブの直下に置いてください。
注意してほしいのは、boostの設定はかなり時間がかかります。
恐ろしいほど時間がかかります。
なのでファイルを操作しているときは、気長に待ちましょう。
私はzipファイルの展開に30分かかっています。
ディレクトリの位置に注意してください。

次にコマンドプロンプト(cmd)でboostをインストールします。
○○はユーザーネームです。

cmd
C:\Users\○○ > cd C:\boost_1_70_0
C:\boost_1_70_0>bootstrap.bat

bootstrap.batの実行結果。

cmd
Building Boost.Build engine

Generating Boost.Build configuration in project-config.jam for msvc...

Bootstrapping is done. To build, run:

    .\b2

To adjust configuration, edit 'project-config.jam'.
Further information:

    - Command line help:
    .\b2 --help

    - Getting started guide:
    http://boost.org/more/getting_started/windows.html

    - Boost.Build documentation:
    http://www.boost.org/build/

1でVisual Studio 2017をインストールしました。
boostをインストールするときにそれぞれのバージョンに注意してください。
・Visual Studio 2017 はmscv-14.1
・64bit であること x64
またディレクトリの移動せずに以下を入力してboostをインストール。

cmd
b2.exe toolset=msvc-14.1 link=static runtime-link=static,shared --build-dir=build/x64 address-model=64 -j5 install --includedir=C:\boost_1_70_0\include --libdir=C:\boost_1_70_0\stage\lib\x64

※Visual Studio 2017 以外の2019, 2015だとmscv-14.1ではないのでご注意を。
 Visual Studio 2019 のバージョンはmscv-14.2(確認済み)
 Visual Studio 2015 のバージョンはmscv-14.0(未確認)

サンプルプログラムの実行

準備は整いました。
boostに時間がかけられたかもしれませんが、めげずに行きましょう(汗)。

新規プロジェクトを作成

Visual Studio 2017を起動して、新規のプロジェクトを起動します。
C++でコンソールアプリを選択。
今回のプロジェクト名をtest_Cplus2_Pythonとしました。

プロジェクトのプロパティを設定

プロジェクトを右クリくして、プロパティを選択。
設定項目は4つです。
1. ソリューション構成とソリューションプラットホームの変更。
プロパティページとメイン画面の両方で設定する。
この設定変更を忘れがちです。
2. boostとPythonをインクルード。
3. マルチスレッドに設定。
4. boostとPythonの.libファイルをリンク。

プロパティページの設定
1. ソリューション構成とソリューションプラットホーム
Debug → Release に変更
x86 → x64

2. C++ → 全般 → 追加のインクルード
C:\boost_1_70_0
C:\Users\○○\AppData\Local\Programs\Python\Python37\include

3. C++ → コード生成 → ランタイムライブラリで 
マルチスレッド(/MT)に変更

4. リンカー → 全般 → 追加のライブラリディレクトリ
C:\boost_1_70_0\stage\lib\x64
C:\Users\○○\AppData\Local\Programs\Python\Python37\libs

設定項目を赤い外枠で囲みました。
○○はユーザー名です。

一度だけ実行

プロジェクトのプロパティ設定ができたら、一度プログラムを実行します。
実行することによってプロジェクトが動くことの確認と.exeファイルを作成ができます。
Hello world! がでれば大丈夫です。

C++とPythonのサンプルコード

C++でPythonとPythonのファイル(.py)を呼ぶので、それぞれにコードを書き込まなくてはいけません。
C++はVisual Studio上に書き込み、Pythonはテキストを新規で作成して、下のテストコードを書く込んでください。

C++に関しては、pythonの名前空間を定義し、関数を

test_Cplus2_with_Python.cpp
#define BOOST_PYTHON_STATIC_LIB

#include <iostream>
#include <boost/python.hpp>

int main()
{
    //名前空間
    namespace py = boost::python;
    //初期化
    Py_Initialize();
    //出力
    std::cout << "Hello World! from C++ \n";

    //Pythonのファイル(test_py.py)をインポート
    py::object module_ns = py::import("test_py").attr("__dict__");
    //インポートしたファイル内の関数を定義
    py::object get_and_return = module_ns["hello_from_python"];
    //インポートした関数を実行
    auto return_nd_array = get_and_return();
}

呼び込むPythonファイルを以下のようにシンプルな処理にします。

test_py.py
def hello_from_python():
        print("Hello World! from Python")

フォルダ構成

先程作成したC++のコードは
test_Cplus2_with_Python→test_Cplus2_with_Python.cppへ書き込み、
Pythonのコードはx64→Release→test_py.pyを配置します。

フォルダ構成
test_Cplus2_with_Python(自作フォルダ)
 ├── test_Cplus2_with_Python
 │  ├── test_Cplus2_with_Python.cpp 〇
 │  ├── test_Cplus2_with_Python.vcxproj
 │  ├── test_Cplus2_with_Python.vcxproj.filters
 │  ├── test_Cplus2_with_Python.vcxproj.user
 │  └── x64
 │  
 ├── x64 
 │  └── Release
 │       ├── test_Cplus2_with_Python.exe
 │       ├── test_Cplus2_with_Python.iobj
 │       ├── test_Cplus2_with_Python.ipdb
 │       ├── test_Cplus2_with_Python.pdb
 │       └── test_py.py 〇
 │ 
 └── test_Cplus2_with_Python.sln

実行結果

C++とPythonのそれぞれの文字列を出力できたら成功です。

できない場合は、
・プロジェクトページでの設定が間違っている
・Pythonファイルのコードが間違っている
・Pythonファイルの配置位置は間違っている
・boostのインストールが間違っている
などがあげられます。

反省

C++でPythonを呼ぶことなんて、そうそうあることではないと思います。
活用方法としては、C++でPythonの深層学習ツールを使用するときに有効です。
後輩を含め、様々な人のお役に立てることを心からお祈りしています。
余裕があったら、C++にPythonの深層学習を用いた物体検出手法(YOLOv3)の実装を載せたいと思います。

Github

ご参考にどうぞ。

URL
git clone https://github.com/yusa0827/200121_Cplus2_with_Python

クローンして実行してもうまく行かないです。
visual studio 内のご自身の環境パスを再設定してください。