Python からC# DLL を呼ぶ
DLL を作る
VS2022, C# Class Library (.Net Framework) project name PyDLL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PyDLL
{
public class Class1
{
// New
public unsafe void TestPy(String strPair, int nCols, IntPtr data, int size)
{
float* array = (float*)data.ToPointer();
for (int i = 0; i < size; i++)
{
for (int c = 0; c < nCols; c++)
{
array[nCols * i + c] = nCols * i + nCols;
}
}
}
}
}
Python からC# DLL の関数を呼ぶ。
Pythonnet を使う
# pip install pythonnet
PyDLL.py
import sys
import clr
import numpy as np
import pandas as pd
from System import IntPtr
# For pythonnet .Net DLL
sys.path.insert(0, 'D:/dai_work/C#/PyDLL/PyDLL/bin/Debug')
# D:\dai_work\C#\PyDLL\PyDLL\bin\Debug\PyDLL.dll
clr.AddReference('PyDLL')
from PyDLL import Class1
class1 = Class1()
steps = 1000
cols = 5
data = np.zeros((steps, cols), dtype=np.float32)
class1.TestPy('Test', cols, IntPtr.op_Explicit(data.ctypes.data), len(data))
# Array => Pandas DataFrame
columns = [f'col_{c}' for c in range(cols)]
df = pd.DataFrame(data, columns=columns)
print(df)
String やInt はそのまま渡せる。シンプルなClassやList もReturn できる。ただしReturn 渡しはマーシャリング(プロセス間コピー)が発生するため、大容量データには向かない。Python 側でメモリ確保し、ポインタ渡しすると速い。