28 November 2024
Developers may encounter situations where they already have a well-established and tested C# library that performs its functions excellently. However, their clients work in a Python environment and need access to the functionality of this library. In such cases, developers need to find ways to integrate, making the C# library accessible for use in Python. In this article, we will examine two approaches to solving this task—wrapping and code conversion—as well as discuss their advantages and disadvantages. This will help you choose the most suitable method and ensure easy access to the functionality of your C# library in Python.
As mentioned earlier, there are two main methods for integrating C# code into the Python environment: wrapping and code conversion.
Let’s take a closer look at each of these methods.
Converting code between programming languages can be a challenging task, especially when the languages have different paradigms and syntactic features. However, many basic constructs of C# and Python are similar, so the conversion process, in simple cases, boils down to syntax changes and the adaptation of certain concepts.
Example of a C# library (MyLibrary.cs)
using System;
namespace MyLibrary
{
public class Greeting
{
public string SayHello(string name)
{
return $"Hello, {name}!";
}
}
}
Translation of the library into Python (mylibrary.py)
class Greeting:
def say_hello(self, name):
return f"Hello, {name}!"
Example of using the translated library in a Python project
# Import our class
from mylibrary import Greeting
# Create an instance of the Greeting class
greet = Greeting()
# Use the say_hello method
message = greet.say_hello("World")
print(message)
In such a simple example, the conversion looks very appealing, doesn't it? But let's take a look at the advantages and disadvantages of this method.
For example, converting the following code to Python would be very challenging:
using System;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace MyLibrary
{
public class Greeting
{
public string SayHello(string name)
{
var tree = CSharpSyntaxTree.ParseText($"public class Hello {{ public string Name => \"{name}\"; }}");
var root = (CompilationUnitSyntax)tree.GetRoot();
var classDeclaration = (ClassDeclarationSyntax)root.Members[0];
var className = classDeclaration.Identifier.Text;
return $"Parsed class name: {className}";
}
}
}
Very often, issues of labor intensity, performance, and external dependencies can become critical, leading to the consideration of another method for integrating C# libraries into Python—creating a wrapper.
Wrapping C# code involves creating an interface that links C# code with Python, using specialized libraries or tools. This allows calling methods written in C# directly from Python code. The advantage of this approach is that it doesn't require rewriting the existing code, saving time and effort—the original C# code remains unchanged. Additionally, you can leverage all the capabilities of the .NET ecosystem without worrying about porting these functions to Python.
There are several methods for wrapping C# code, with the most popular being the use of the Python.NET library and specialized tools like our CodePorting.Wrapper Cs2Python.
The aforementioned C# library MyLibrary
can be used in Python as follows:
import clr
clr.AddReference("MyLibrary.dll")
from MyLibrary import Greeting
greet = Greeting()
message = greet.SayHello("World")
print(message)
If there are dependencies on Microsoft.CodeAnalysis
, the situation becomes more complex:
import clr
# Adding all dependencies
clr.AddReference("Microsoft.CodeAnalysis.dll")
clr.AddReference("Microsoft.CodeAnalysis.CSharp.dll")
...
clr.AddReference("System.Collections.Immutable.dll")
clr.AddReference("MyLibrary.dll")
from MyLibrary import Greeting
greet = Greeting()
message = greet.SayHello("World")
print(message)
The necessity of explicitly connecting external dependencies and other limitations, such as difficulties with passing certain data types, can complicate the use of the Python.NET library for integrating C# code. In such cases, it is worth considering alternative tools that may offer more convenient and automated solutions.
CodePorting.Wrapper Cs2Python provides a convenient way to integrate a C# library into Python by creating a standard Python extension in the form of a Wheel package (WHL), which can be easily installed via pip
and used in Python projects. This tool automatically generates an intermediate layer that links C# code with Python. Moreover, all dependencies of the C# library are automatically included in the package.
Using the MyLibrary
library wrapped with CodePorting.Wrapper Cs2Python in both cases will look like this:
from mylibrary import Greeting
greet = Greeting()
message = greet.say_hello("World")
print(message)
As you can see, this exactly replicates the usage example in the case of full code conversion. However, we did not have to convert the Microsoft.CodeAnalysis
code to Python or find its equivalent.
Now let's consider the advantages and disadvantages of integrating C# code into Python using wrapping.
pip
makes the process simple and intuitive. This allows users to easily integrate and use the library's functionality in their projects without requiring deep technical knowledge.Integrating C# libraries into Python allows you to effectively use existing C# code in Python projects. The choice between wrapping and code conversion depends on the specific needs of the project. Wrapping allows you to quickly and easily use C# libraries in Python, minimizing time and effort. Code conversion requires more resources but can provide deeper integration.
The right choice of integration method will help you maximize the use of resources and achieve your goals.