0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++】32bit C++からPythonを利用する(VisualStudio)

Last updated at Posted at 2021-10-09

はじめに

  • 本記事では、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のみが存在する状態にしておいた方が良いです。

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を置かなければならない
    • 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

PCの環境変数の設定

  • 筆者の環境では特にいじる必要がなかったが、もしうまくいかない場合は環境変数を確認するとよいかも
    • PCに複数のPythonバージョンがインストールされていたり、Anacondaを利用している場合、環境変数あたりで苦戦するはず。

C++からPythonを利用する

Boost Python 使用時の作法

  • プログラムを作成する際に気を付ける点をまとめる
    • プログラムの初めに Py_Initialize(); を、 プログラムの終わりにPy_Finalize(); (必須ではない)をつけること

    • Boost::numpy を使用する際は、np::initialize(); もつけること

    • プログラム全体を try-catchで囲み、キャッチした例外をPrint()できるようにすること

      main.py
      int 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++ソースファイルの場所になることに注意。(ファイルパスが通らない場合確認のこと)

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?