Calling C# DLL in Python

Create 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;
                }
            }
        }
    }
}

Call a C # DLL function from Python.

Using 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 and Int can be passed as they are. Simple Class and List can also be returned. However, Return pass is not suitable for large volumes of data because it causes marshalling (interprocess copy). It is fast if you allocate memory on the Python side and pass a pointer.