Python.NET

【Python.NET】PythonからC#ライブラリ(dll)の使用方法

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#のメソッドで引数にrefoutを点けて参照渡しにしているメソッドは、Python側の引数に値が戻ってくる事はなく、Python.NET側で勝手にタプルになって、値が戻されます。

 

まとめ

Python.NETを使うと、C#のDLLに手を加える事なく、そのまま使用する事が出来るようになります。

私の仕事では、まだまだ.NET Frameworkを使う事が多く、自社製品もC#の対応は、ほぼ、行っていますが、Pythonの対応は出来ていないというのが現状です。

しかしながら、画像を撮り込んでDeepLearningをしたいとなると、やはりPythonでカメラの撮影をしたくなるので、とりあえず、Python.NETを使うと、何もすること無くC#のライブラリがPythonから使えてしまうのは、とてもありがたいです。

参考

Embedding .NET into Python - Python.NET documentation

コメント

  1. mishima より:

    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の設定でビルドしています。

    何が問題なのか、教えていただけないでしょうか。

    • Akira より:

      コメントありがとうございます。

      import CSharpDLL as calc

      の部分は、ライブラリの名前空間(namespace)を指定する部分なので、お使いのDLLの名前空間を指定してみてください。

タイトルとURLをコピーしました