Original article:
- https://www.red-gate.com/simple-talk/dotnet/net-framework/dynamic-language-integration-in-a-c-world/
Pythonnet:
Table of contents
Calling C# Methods from Python
In the following example, I’ll perform the reverse operation; creating the calculator’s class in C# and then accessing it from Python. There is no attached demonstration for this, and it does not significantly inform the final build of the application, so this is primarily an academic exercise.
Create the C# Class
1. In Visual Studio, create a new C# Class Library project with the name DynamicCS;
2. Create a standard C# class in the DynamicCS project by renaming the existing Class1.cs class to Calculator.cs. Implement two simple methods for adding and subtracting numbers, as follows:
using System;
namespace DynamicCS
{
public class Calculator
{
public double add(double argA, double argB)
{
return argA + argB;
}
public double sub(double argA, double argB)
{
return argA - argB;
}
}
}
The Calculator class is a valid C# class, but to access it as a dynamic object from Python, you need to have a wrapper class that inherits from DynamicObject, as demonstrated over the remaining steps:
3. In the Solution Explorer, right-click the DynamicCS project file, and select Add > New Item > Class;
4. In the Solution Explorer, rename the new file to DynamicCalc.cs;
5. In the newly-created class, add:
using System.Dynamic
6. Define a public DynamicCalc class that derives from DynamicObject:
public class DynamicCalc: DynamicObject
7. Implement the constructor of the DynamicCalc class:
public DynamicCalc()
{
calc = new Calculator();
}
8. Override methods from the DynamicObject class. In the presented example, the TryGetMember method has to be overridden, at the very least:
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
}
9. The resulting DynamicCalc.cs file might look like this:
namespace DynamicCS
{
public class DynamicCalc: DynamicObject
{
Calculator calc;
public DynamicCalc()
{
calc = new Calculator();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
switch (binder.Name)
{
case "add":
result = (Func<double, double, double>) ((double a, double b)
=> calc.add(a, b));
return true;
case "sub":
result = (Func<double, double, double>) ((double a, double b)
=> calc.sub(a, b));
return true;
}
return false;
}
}
}
Note that, in the TryGetMember method:
- binder.Name represents a name of the method or property called;
- result is an output value of the method or property. In this case, it is a delegate to the ‘add’ and ‘sub’ methods of the calc object;
- return should return ‘true’ if the operation is successful, otherwise ‘false’.
Finally, save and build the solution. The Python executable performs the calculations by calling the calc object, which in turn resolves the result of the C# DynamicCalc class, imported from DynamicCS.dll.
Call the C# Methods from Python
1. In the Solution Explorer, right click the DynamicCS project file, and select Add > New Item > Text file;
2. In the Solution Explorer, rename the new file to client.py;
3. Add an import sys statement, pointing to the directory where your C# DLL is located. In this example, I have saved DynamicCS.dll in C:\MyProjects\DynamicCS\DynamicCS\bin\Debug:
import sys
sys.path.append(r"C:\MyProjects\DynamicCS\DynamicCS\bin\Debug")
4. Reference your C# DLL:
import clr
clr.AddReference(r"DynamicCS.dll")
5. Create a Python object as you would for any other object, then use it to perform some calculations:
from DynamicCS import DynamicCalc
calc=DynamicCalc()
6. The resulting client.py file might look like this:
import sys
sys.path.append(r"C:\MyProjects\DynamicCS\DynamicCS\bin\Debug")
import clr
clr.AddReference(r"DynamicCS.dll")
from DynamicCS import DynamicCalc
calc=DynamicCalc()
print calc.__class__.__name__
# display the name of the class: 'DynamicCalc'
a=7.5
b=2.5
res = calc.add(a, b)
print a, '+', b, '=', res
res = calc.sub(a, b)
print a, '-', b, '=', res
raw_input('Press any key to finish...')
7. Save and run the Python client.
- Figure 2. The basic calculator, implemented mostly in Python. Creating and calling Python methods in C#
The Python executable performs the calculations by calling the calc object, which in turn resolves the result of the C# DynamicCalc class, imported from DynamicCS.dll. The end result looks much the same as the earlier implementation.