C#でpythonで書いた機能を実行する方法まとめ
概要
C#を使って作っているwindowsアプリケーションにpythonで書いた機能を組み込みたくなることがあります。具体的には機械学習とか画像認識とかですね。そんな時に使える方法はいくつかあるのでまとめてみました。
1. Process.startで.pyファイルを実行する
Processクラスのstartメソッドを使うと外部ファイルを実行できます。(参考)
Dim psi As New System.Diagnostics.ProcessStartInfo()
psi.FileName = "python.exe"
psi.Arguments = "pyfile.py"
System.Diagnostics.Process.Start(psi)
ProcessStartInfoのFileNameにpython.exeのパスを、Argumentsに実行したいpyファイルのパスを指定します。
引数が必要ならばArgumentsに空白で区切って渡せます。
返り値が必要ならば標準出力で受け取ることができます。
メリット
・モジュールのインストールが不要
ironpythonやpythonnetのようにモジュールをインストールして設定をして、、、という手間はかかりません。
・保守性
pythonコードを変更したくなった場合、.pyファイルだけを置き換えればいいので保守はしやすいです。
デメリット
・配布先にpython環境が必要
使用するPCにpythonがインストールされていることが前提となります。exeファイルとして第3者に渡す場合は注意が必要です。
・遅い
外部ファイルを呼び出して結果を再度受け取るのでどうしても遅くなります。
2. PyInstallerでexe化し、Process.startで実行
pyInstallerというモジュールを使えば.pyファイルをexe化できるのでそれをProcess.startで実行することもできます。
メリット
・配布先にpython環境が不要
exe化してしまえば配布先のPCにpythonが入っていなくても実行できます。
デメリット
・使い勝手
このモジュールは少し癖があって、僕のPCではエラーが出て実行できませんでした(たぶん僕がそういうのに弱いだけなんですが、、、)。
あと、出力されるexeは数百MBになったりします。
・遅い
これも1と同じく遅いです。
3. IronPython
.net上でpythonを実行するためのpython環境としてIronPythonがあります。(参考)
メリット
・配布先にpython環境が不要
これも最終的にexeにまとめることができます。
・連携が簡単
C#の中にpythonプログラムを組み込めるので、引数や結果の受け渡しが容易にできます。
・(上の2つよりは)速い
外部ファイルを呼び出さないので上の2つと比べたら実行速度は速くなります。
デメリット
・python環境が別に必要
既存のpython環境とは別でIronpythonの環境が必要になります。
・安定版がpython2系
すでにpython3系で書いてしまったプログラムを実行したい場合は注意が必要です。
・保守性
pythonコードを組み込む場合は、pythonコードを変更するたびにアプリ全体をリビルドする必要があります。.pyファイルを呼び出す場合はこの限りではありませんが、実行速度は遅くなります。
4. pythonnet
こちらも.netでpythonを使えるようにするライブラリです。(参考)僕は使ったことないので以下は他の記事を参考に書いています。
メリット
・連携が簡単
C#の中にpythonプログラムを組み込めるので、引数や結果の受け渡しが容易にできます。
・(1、2よりは)速い
外部ファイルを呼び出さないので上の2つと比べたら実行速度は速くなります。
デメリット
・環境構築が大変(参考)
・配布先にpython環境が必要
pythonパスを通してるということはpython環境が必要なはず(多分)
・保守性
pythonコードを組み込む場合は、pythonコードを変更するたびにアプリ全体をリビルドする必要があります。.pyファイルを呼び出す場合はこの限りではありませんが、実行速度は遅くなります。
5. cythonでラップしてdllとしてビルド
cythonでpythonコードを書けばC/C++からそのコードを利用することができます。VC++などでそのcythonコードをdllにすればC#からも呼び出すことができます。
メリット
・速い
dllとしてロードしているので実行速度は他と比べて速いと思います(測ったわけではありませんが)。
デメリット
・設定が大変
特にC++でビルドするのに慣れていないと大変ですね。
・配布先にpython環境が必要
これもpython環境が必要です。
・保守性
pythonコードを変更したくなった場合、pythonコードとdllの両方を修正しないといけないので保守性が悪いです。
6. C++でdllを作る
「pythonコードを呼び出す」という前提を覆してしまいますが、機械学習や画像認識などのライブラリはC++用APIもあったりします(pytorch、tensorflow、opencvはあります。)
メリット
・速い
dllとしてロードするので実行速度は速いと思います。
・配布先にpython環境が不要
当たり前ですが上記の多くの方法が抱えている、「配布先にpython環境が必要」という問題は生じません。
デメリット
・C++用APIが必要
scikit-learnはC++用APIがないのでこの方法は使えません。
・コードの書き直しが必要
すでにpythonでコードを書いてしまっている場合は2度手間になってしまいます。
まとめ
上記をまとめると以下のようになります。
(※実行速度は測って比較したわけではありません)
(※環境構築の難しさは個人の感覚によります)
ちなみに、anacondaの仮想環境をフォルダごとコピーして一緒に配布すれば配布先にpythonが入っていなくても一応実行できます(あんまりオススメしませんが)。(参考)
結局どれがいい?
C++用APIがあって、C++を書いた経験があるならC++でdllを作るのがいいと思います。そうでない場合は、exeとして配布するデスクトップアプリならば配布先にpython環境が不要なIronpythonかProcessでexeを実行、webアプリならばIronpythonかpythonnnetがいいと思います。あとは環境構築が苦じゃないか、どれぐらい頻繁にpythonコードを変更するか、どの程度実行速度が求められるか、といった事柄を勘案して決めてください。
最新記事
すべて表示概要 pythonでデータ解析を行っている。解析自体はpandasを用いて行い、最終結果はpandas.DataFrameの形式で保持されている。 この結果を他のアプリケーションで利用するため、json形式でファイル出力したい。 やり方 1...
現象 raspberry piでfirestoreをimportしようとするとタイトルのエラーが発生。 from from firebase_admin import firestore ImportError: Failed to import the Cloud...
現象 C#で下記のコードでタイトルのコンパイルエラーが発生。 このエラーは、例えばclassがprivateなのにメソッドがpublicといった場合に発生するのだが、この例ではどちらもpublic public class MyClass{ public...
Comments