Python.NET(pythonnet)を使うと、C#というか、.NETで作られたライブラリ(dll)を、何も手を加える事なく、そのままPythonから使う事が出来るようになります。
また、その逆のC#からPythonのモジュールを使う事も可能です。
今回は、.NET Frameworkで作られたライブラリ(dll)をPythonから使う方法を紹介します。
Python.NET(pythonnet)のインストール
これはpipでインストールできるので、簡単です。
pip install pythonnet
以降、具体的な例を示します。
C#ライブラリのサンプル例
今回はC#で作られたライブラリの例として、以下の用な物を用意しました。
DLLファイル名はCSharpDLL.dllとしました。
通常は、既存のDLLファイルをそのまま使う事が出来るので、わざわざC#のDLLを作成する必要はありません。
namespace CSharpDLL
{
public class Calculation
{
// intの足し算
public int Add(int a, int b)
{
return a + b;
}
// floatの足し算
public float Add(float a, float b)
{
return a + b;
}
// stringの足し算(文字列の結合)
public string Add(string a, string b)
{
return a + b;
}
// 結果を引数(outの参照渡し)で返す場合
public bool Add_ref(int a, int b, out int ans)
{
ans = a + b;
return true;
}
// 結果を引数(refの参照渡し)で返す場合
public bool Add_out(int a, int b, ref int ans)
{
ans += a + b;
return true;
}
}
}
PythonからC#のライブラリを使用する方法
まずは、PythonからC#のDLLを使うサンプルを以下に示します。
import clr # Python.net
# dllファイルの参照追加(拡張子なしで指定)
clr.AddReference("CSharpDLL")
# 名前空間の追加
import CSharpDLL as calc
# クラスのインスタンス(newは付かない)
cal = calc.Calculation()
# intの足し算
ret = cal.Add(1, 2)
print(ret, type(ret))
# floatの足し算
ret = cal.Add(1.5, 2.1)
print(ret, type(ret))
# stringの足し算(文字列の結合)
ret = cal.Add("1", "2")
print(ret, type(ret))
# 結果を引数(refの参照渡し)で返す場合
ans_ref = 5
ret, ans = cal.Add_ref(1, 2, ans_ref)
print(ret, ans, ans_ref)
# 結果を引数(outの参照渡し)で返す場合
ans_out = 5
ret, ans = cal.Add_out(1, 2, ans_out)
print(ret, ans, ans_out)
Python.NET(pythonnet)のインポート
import clr
これで、Python.NETのインポートになっています。なぜだか clr ??
使用するC#のDLLファイルの参照設定
clr.AddReference("CSharpDLL")
AddReference関数で、使用するライブラリのファイル名を拡張子なしで指定します。
実際のDLLファイルは、実行するPythonのファイル(.py)から参照できる位置にある必要があります。
例えば、Pythonのファイルと同一フォルダや、環境変数のPATHで指定されているフォルダに使用するDLLファイルを配置してください。
C#ライブラリの名前空間のインポート
使用するライブラリのクラスの名前空間をインポートします。
import CSharpDLL as calc
クラスのインスタンス
cal = calc.Calculation()
C#に慣れていると、ただ、メソッドを呼んでいるように見えますが、上記の書き方でクラスをインスタンスしています。(new とかは付きません)
メソッドの実行例
# intの足し算
ret = cal.Add(1, 2)
print(ret, type(ret))
# floatの足し算
ret = cal.Add(1.5, 2.1)
print(ret, type(ret))
# stringの足し算(文字列の結合)
ret = cal.Add("1", "2")
print(ret, type(ret))
# 結果を引数(refの参照渡し)で返す場合
ans_ref = 5
ret, ans = cal.Add_ref(1, 2, ans_ref)
print(ret, ans, ans_ref)
# 結果を引数(outの参照渡し)で返す場合
ans_out = 5
ret, ans = cal.Add_out(1, 2, ans_out)
print(ret, ans, ans_out)
実行結果
3 <class ‘int’> 3.5999999046325684 <class ‘float’> 12 <class ‘str’> True 3 5 True 8 5 |
今回は、C#側でAddというメソッドをいくつかのオーバーロードを用意して、Python側から呼び出しています。
Pythonからでも、ほぼ、C#と同じ感覚でメソッドを呼び出す事ができます。
少々異なるのが、C#のメソッドで引数にrefやoutを点けて参照渡しにしているメソッドは、Python側の引数に値が戻ってくる事はなく、Python.NET側で勝手にタプルになって、値が戻されます。
まとめ
Python.NETを使うと、C#のDLLに手を加える事なく、そのまま使用する事が出来るようになります。
私の仕事では、まだまだ.NET Frameworkを使う事が多く、自社製品もC#の対応は、ほぼ、行っていますが、Pythonの対応は出来ていないというのが現状です。
しかしながら、画像を撮り込んでDeepLearningをしたいとなると、やはりPythonでカメラの撮影をしたくなるので、とりあえず、Python.NETを使うと、何もすること無くC#のライブラリがPythonから使えてしまうのは、とてもありがたいです。
参考
https://pythonnet.github.io/pythonnet/python.html
pythonnetの記事、大変参考になります。
このサンプルコードで試したのですが、以下の行で
import CSharpDLL as calc
以下のエラーが出ます。
ModuleNotFoundError: No module named ‘CSharpDLL’
Pythonは以下のバージョンです。
3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]
DLLは、「Visual Studio Community 2022」を使って64bitの設定でビルドしています。
何が問題なのか、教えていただけないでしょうか。
コメントありがとうございます。
import CSharpDLL as calc
の部分は、ライブラリの名前空間(namespace)を指定する部分なので、お使いのDLLの名前空間を指定してみてください。