在Linux环境中,Python可以通过pythonnet
(CLR的Python绑定)或subprocess
调用C#动态库。以下是两种方法的示例:
方法1:使用pythonnet
(推荐)
前提条件
- 安装Mono或.NET Core运行时
- 安装
pythonnet
包:bash
pip install pythonnet
示例步骤
- C# 动态库代码 (
MyLibrary.cs
):
csharp
using System;namespace MyLibrary
{public class Calculator{public int Add(int a, int b) => a + b;public static string Greet(string name) => $"Hello, {name}!";}
}
- 编译C#为动态库:
bash
# 使用Mono编译
mcs -target:library -out:MyLibrary.dll MyLibrary.cs# 或使用.NET Core
dotnet publish --configuration Release --output ./out
- Python调用代码:
python
import os# ===== 关键设置:强制使用 .NET Core =====
os.environ["PYTHONNET_RUNTIME"] = "coreclr" # 必须在 import clr 之前!
os.environ["DOTNET_ROOT"] = "/usr/share/dotnet" # 确保路径正确(可通过 `which dotnet` 确认)# ===== 加载 .NET 库 =====
import clr
clr.AddReference("./MyLibrary.dll")from MyLibrary import Calculator# ===== 调用方法 =====
calc = Calculator()
result = calc.Add(3, 4) # 调用实例方法
print(f"3 + 4 = {result}") # 输出: 3 + 4 = 7message = Calculator.Greet("World") # 调用静态方法
print(message) # 输出: Hello, World!
方法2:通过subprocess
调用(通用方案)
如果pythonnet
不可用,可以通过命令行调用C#程序。
- C# 可执行程序 (
Program.cs
):
csharp
using System;class Program
{static void Main(string[] args){if (args.Length > 0 && args[0] == "add"){int a = int.Parse(args[1]);int b = int.Parse(args[2]);Console.WriteLine(a + b);}}
}
- 编译并运行:
bash
# 编译
mcs -out:Program.exe Program.cs# Python调用
import subprocessdef add_numbers(a, b):result = subprocess.run(["mono", "Program.exe", "add", str(a), str(b)],stdout=subprocess.PIPE,text=True)return int(result.stdout)print(add_numbers(5, 3)) # 输出: 8
关键注意事项
-
运行时依赖:
- 必须安装Mono (
sudo apt install mono-complete
) 或.NET Core pythonnet
在Linux上需要libgdiplus
(部分系统需手动安装)
- 必须安装Mono (
-
路径问题:
- 动态库路径需使用绝对路径或确保Python工作目录正确
-
跨平台兼容性:
- 若使用.NET Core,编译时指定运行时标识符(如
linux-x64
)
- 若使用.NET Core,编译时指定运行时标识符(如
-
性能考虑:
pythonnet
适合高频调用,subprocess
适合低频简单调用
故障排查
-
如果
clr.AddReference
失败,尝试:python
import os os.environ["MONO_GAC_PREFIX"] = "/usr" # 或Mono的实际安装路径
-
确保动态库架构与Python解释器匹配(同为x64或x86)