C#でpythonで書いた機能を実行する方法まとめ
top of page

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.DataFrameをjsonで出力

概要 pythonでデータ解析を行っている。解析自体はpandasを用いて行い、最終結果はpandas.DataFrameの形式で保持されている。 この結果を他のアプリケーションで利用するため、json形式でファイル出力したい。 やり方 1 pandas.DataFrameをdictionaryに変換 data = df.to_dict(orient='records') 2 ファイルに出力 wi

[C#] アクセシビリティに一貫性がありません

現象 C#で下記のコードでタイトルのコンパイルエラーが発生。 このエラーは、例えばclassがprivateなのにメソッドがpublicといった場合に発生するのだが、この例ではどちらもpublic public class MyClass{ public MyClass(OtherClass data){ //ここでエラー //略 } 原因と解決策 コンストラクタ

あなたの買い物をサポートする
アプリ Shop Plan

iphone6.5p2.png

​いつ何を買うかの計画を立てられるアプリです。

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

靴を大切にしよう!靴管理アプリ SHOES_KEEP

納品:iPhone6.5①.png

靴の履いた回数、お手入れ回数を管理するアプリです。

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

「後で読む」を忘れないアプリ ArticleReminder

気になった​Webサイトを登録し、指定時刻にリマインダを送れるアプリです

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png
bottom of page