在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)