最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python調(diào)用C# dll的兩種主要方法

 更新時(shí)間:2025年11月12日 09:01:00   作者:學(xué)亮編程手記  
這篇文章主要介紹了兩種方法讓Python調(diào)用C# DLL:推薦的pythonnet方法和使用COM組件的方法,每種方法都有詳細(xì)的步驟,包括創(chuàng)建和編譯C#項(xiàng)目、安裝Python依賴、運(yùn)行測試等,文章還討論了注意事項(xiàng),如架構(gòu)匹配、依賴項(xiàng)、異常處理和性能優(yōu)化,需要的朋友可以參考下

Python 調(diào)用 C# DLL 的完整案例

下面提供兩種主要方法:使用 pythonnet (推薦) 和使用 COM 組件。

方法一:使用 pythonnet (clr) - 推薦

1. 創(chuàng)建 C# 類庫項(xiàng)目

MathOperations.cs

using System;
using System.Runtime.InteropServices;

namespace CSharpDLL
{
    [ComVisible(true)]  // 使類對 COM 可見
    [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]  // 唯一標(biāo)識(shí)符
    public interface IMathOperations
    {
        int Add(int a, int b);
        double Multiply(double a, double b);
        string Greet(string name);
        double[] ProcessArray(double[] numbers);
        Person ProcessPerson(Person person);
    }

    [ComVisible(true)]
    [Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71")]
    [ClassInterface(ClassInterfaceType.None)]
    public class MathOperations : IMathOperations
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public double Multiply(double a, double b)
        {
            return a * b;
        }

        public string Greet(string name)
        {
            return $"Hello, {name}! from C# DLL";
        }

        public double[] ProcessArray(double[] numbers)
        {
            if (numbers == null)
                return null;

            double[] result = new double[numbers.Length];
            for (int i = 0; i < numbers.Length; i++)
            {
                result[i] = numbers[i] * 2 + 1;  // 簡單的處理:2*x + 1
            }
            return result;
        }

        public Person ProcessPerson(Person person)
        {
            if (person == null)
                return null;

            return new Person
            {
                Name = person.Name.ToUpper(),
                Age = person.Age + 1,
                Score = person.Score * 1.1
            };
        }

        // 靜態(tài)方法
        public static string GetVersion()
        {
            return "CSharpDLL v1.0.0";
        }

        // 重載方法示例
        public string ProcessData(string data)
        {
            return $"Processed string: {data}";
        }

        public string ProcessData(int data)
        {
            return $"Processed int: {data}";
        }

        public string ProcessData(double data)
        {
            return $"Processed double: {data:F2}";
        }
    }

    [ComVisible(true)]
    [Guid("F54F8C0A-69B5-4BC5-9E2A-123456789ABC")]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public double Score { get; set; }

        public override string ToString()
        {
            return $"Person: {Name}, Age: {Age}, Score: {Score}";
        }
    }

    // 高級(jí)功能示例
    [ComVisible(true)]
    [Guid("12345678-1234-1234-1234-123456789DEF")]
    public class AdvancedOperations
    {
        // 回調(diào)函數(shù)示例
        public delegate void ProgressCallback(int progress, string message);
        
        public void LongRunningOperation(ProgressCallback callback)
        {
            for (int i = 0; i <= 100; i += 10)
            {
                System.Threading.Thread.Sleep(500);
                callback?.Invoke(i, $"Progress: {i}%");
            }
        }

        // 事件示例
        public event EventHandler<string> OperationCompleted;

        public void StartOperation()
        {
            System.Threading.Thread.Sleep(1000);
            OperationCompleted?.Invoke(this, "Operation completed successfully!");
        }

        // 異常處理示例
        public double SafeDivide(double a, double b)
        {
            if (b == 0)
                throw new DivideByZeroException("Division by zero is not allowed");
            return a / b;
        }
    }
}

AssemblyInfo.cs (重要:添加強(qiáng)名和COM注冊信息)

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("CSharpDLL")]
[assembly: AssemblyDescription("C# DLL for Python interop")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CSharpDLL")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(true)]
[assembly: Guid("a13cc3d7-6c1e-4b5a-93a7-2e4c073d7a9a")]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

2. 編譯 C# 項(xiàng)目

使用 Visual Studio 或命令行編譯:

csc /target:library /out:CSharpDLL.dll /reference:System.Runtime.InteropServices.dll *.cs

3. Python 端代碼

install_requirements.py

#!/usr/bin/env python3
"""
安裝必要的 Python 包
"""
import subprocess
import sys

def install_package(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

if __name__ == "__main__":
    packages = ["pythonnet", "clr-loader"]
    
    for package in packages:
        try:
            print(f"正在安裝 {package}...")
            install_package(package)
            print(f"{package} 安裝成功!")
        except Exception as e:
            print(f"安裝 {package} 失敗: {e}")

main.py

#!/usr/bin/env python3
"""
Python 調(diào)用 C# DLL 的主程序
"""
import os
import sys
import clr
from typing import List, Dict, Any
import logging

# 設(shè)置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class CSharpDLLManager:
    """C# DLL 管理器"""
    
    def __init__(self, dll_path: str):
        """
        初始化 DLL 管理器
        
        Args:
            dll_path: C# DLL 文件路徑
        """
        self.dll_path = dll_path
        self._loaded = False
        self._math_ops = None
        self._advanced_ops = None
        
    def load_dll(self) -> bool:
        """加載 C# DLL"""
        try:
            # 添加 DLL 所在目錄到 CLR 路徑
            dll_dir = os.path.dirname(os.path.abspath(self.dll_path))
            clr.AddReference(dll_dir)
            
            # 加載 DLL
            clr.AddReference(os.path.basename(self.dll_path).replace('.dll', ''))
            
            # 導(dǎo)入命名空間
            from CSharpDLL import MathOperations, Person, AdvancedOperations
            
            self._math_ops = MathOperations()
            self._advanced_ops = AdvancedOperations()
            self._loaded = True
            
            logger.info("C# DLL 加載成功")
            return True
            
        except Exception as e:
            logger.error(f"加載 C# DLL 失敗: {e}")
            return False
    
    def test_basic_operations(self) -> Dict[str, Any]:
        """測試基本操作"""
        if not self._loaded or not self._math_ops:
            raise RuntimeError("DLL 未加載")
        
        results = {}
        
        # 測試整數(shù)運(yùn)算
        results['add'] = self._math_ops.Add(10, 20)
        
        # 測試浮點(diǎn)數(shù)運(yùn)算
        results['multiply'] = self._math_ops.Multiply(3.14, 2.5)
        
        # 測試字符串處理
        results['greet'] = self._math_ops.Greet("Python")
        
        # 測試數(shù)組處理
        input_array = [1.0, 2.0, 3.0, 4.0, 5.0]
        results['array_input'] = input_array
        results['array_output'] = list(self._math_ops.ProcessArray(input_array))
        
        # 測試對象處理
        person = Person()
        person.Name = "Alice"
        person.Age = 25
        person.Score = 95.5
        
        processed_person = self._math_ops.ProcessPerson(person)
        results['person_input'] = str(person)
        results['person_output'] = str(processed_person)
        
        # 測試重載方法
        results['overload_string'] = self._math_ops.ProcessData("test")
        results['overload_int'] = self._math_ops.ProcessData(42)
        results['overload_double'] = self._math_ops.ProcessData(3.14159)
        
        return results
    
    def test_advanced_operations(self) -> Dict[str, Any]:
        """測試高級(jí)操作"""
        if not self._loaded or not self._advanced_ops:
            raise RuntimeError("DLL 未加載")
        
        results = {}
        
        # 測試回調(diào)函數(shù)
        def progress_callback(progress, message):
            logger.info(f"進(jìn)度回調(diào): {progress}% - {message}")
        
        logger.info("開始測試長時(shí)運(yùn)行操作...")
        self._advanced_ops.LongRunningOperation(progress_callback)
        
        # 測試事件
        def operation_completed(sender, args):
            logger.info(f"操作完成事件: {args}")
            results['event_message'] = args
        
        self._advanced_ops.OperationCompleted += operation_completed
        self._advanced_ops.StartOperation()
        
        # 測試異常處理
        try:
            results['safe_divide_success'] = self._advanced_ops.SafeDivide(10.0, 2.0)
            results['safe_divide_error'] = "No error"
        except Exception as e:
            results['safe_divide_error'] = f"捕獲到異常: {e}"
        
        return results
    
    def run_benchmark(self, iterations: int = 10000) -> Dict[str, Any]:
        """性能測試"""
        if not self._loaded or not self._math_ops:
            raise RuntimeError("DLL 未加載")
        
        import time
        
        start_time = time.time()
        
        for i in range(iterations):
            result = self._math_ops.Add(i, i + 1)
        
        end_time = time.time()
        
        return {
            'iterations': iterations,
            'total_time': end_time - start_time,
            'average_time': (end_time - start_time) / iterations * 1000,  # 毫秒
            'operations_per_second': iterations / (end_time - start_time)
        }

def main():
    """主函數(shù)"""
    # DLL 路徑 - 請根據(jù)實(shí)際情況修改
    dll_path = r"CSharpDLL.dll"  # 或者完整路徑如 r"C:\path\to\CSharpDLL.dll"
    
    if not os.path.exists(dll_path):
        logger.error(f"找不到 DLL 文件: {dll_path}")
        logger.info("請先編譯 C# 項(xiàng)目生成 DLL 文件")
        return
    
    # 創(chuàng)建管理器
    manager = CSharpDLLManager(dll_path)
    
    # 加載 DLL
    if not manager.load_dll():
        return
    
    try:
        # 測試基本操作
        logger.info("=== 測試基本操作 ===")
        basic_results = manager.test_basic_operations()
        
        for key, value in basic_results.items():
            logger.info(f"{key}: {value}")
        
        print("\n" + "="*50 + "\n")
        
        # 測試高級(jí)操作
        logger.info("=== 測試高級(jí)操作 ===")
        advanced_results = manager.test_advanced_operations()
        
        for key, value in advanced_results.items():
            logger.info(f"{key}: {value}")
        
        print("\n" + "="*50 + "\n")
        
        # 性能測試
        logger.info("=== 性能測試 ===")
        benchmark_results = manager.run_benchmark(10000)
        
        for key, value in benchmark_results.items():
            logger.info(f"{key}: {value}")
            
    except Exception as e:
        logger.error(f"測試過程中發(fā)生錯(cuò)誤: {e}")

if __name__ == "__main__":
    main()

方法二:使用 COM 組件

1. C# COM 組件注冊

修改 C# 項(xiàng)目屬性:

  • 在項(xiàng)目屬性中勾選 “Register for COM interop”
  • 或者使用 regasm 手動(dòng)注冊:
regasm CSharpDLL.dll /tlb /codebase

2. Python 使用 COM 組件

com_interop.py

#!/usr/bin/env python3
"""
使用 COM 組件方式調(diào)用 C# DLL
"""
import pythoncom
import win32com.client
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def test_com_interop():
    """測試 COM 互操作"""
    try:
        # 創(chuàng)建 COM 對象
        math_ops = win32com.client.Dispatch("CSharpDLL.MathOperations")
        
        # 測試方法調(diào)用
        result = math_ops.Add(15, 25)
        logger.info(f"15 + 25 = {result}")
        
        result = math_ops.Greet("COM Client")
        logger.info(f"Greeting: {result}")
        
        # 測試數(shù)組處理
        input_array = [1.0, 2.0, 3.0]
        result = math_ops.ProcessArray(input_array)
        logger.info(f"Array input: {input_array}")
        logger.info(f"Array output: {list(result)}")
        
    except Exception as e:
        logger.error(f"COM 互操作失敗: {e}")

if __name__ == "__main__":
    test_com_interop()

完整項(xiàng)目結(jié)構(gòu)

CSharpPythonInterop/
├── CSharpDLL/                    # C# 類庫項(xiàng)目
│   ├── MathOperations.cs
│   ├── Person.cs
│   ├── AdvancedOperations.cs
│   ├── AssemblyInfo.cs
│   └── CSharpDLL.csproj
├── PythonClient/                 # Python 客戶端
│   ├── main.py
│   ├── com_interop.py
│   ├── install_requirements.py
│   └── requirements.txt
└── README.md

使用說明

環(huán)境要求

  • C# 端: .NET Framework 4.7.2+ 或 .NET Core 3.1+/ .NET 5+
  • Python 端: Python 3.7+
  • 必需包: pythonnet (推薦) 或 pywin32 (COM方式)

安裝步驟

編譯 C# DLL:

cd CSharpDLL
dotnet build --configuration Release

安裝 Python 依賴:

cd PythonClient
pip install pythonnet
# 或者
python install_requirements.py

運(yùn)行測試:

python main.py

注意事項(xiàng)

  1. 架構(gòu)匹配: 確保 Python 和 C# DLL 的架構(gòu)一致 (x86/x64)
  2. 依賴項(xiàng): 如果 C# DLL 有依賴項(xiàng),確保它們在同一目錄或 GAC 中
  3. 異常處理: C# 異常會(huì)作為 Python 異常拋出,需要適當(dāng)處理
  4. 性能: 對于高頻調(diào)用,考慮批量操作減少互操作開銷

常見問題解決

  1. DLL 加載失敗: 檢查路徑和依賴項(xiàng)
  2. 類型轉(zhuǎn)換錯(cuò)誤: 確保參數(shù)類型匹配
  3. 內(nèi)存泄漏: 及時(shí)釋放 COM 對象
  4. 線程安全: 在多線程環(huán)境中注意同步

這個(gè)完整案例展示了 Python 調(diào)用 C# DLL 的各種場景,包括基本類型、數(shù)組、對象、回調(diào)、事件和異常處理等。

以上就是Python調(diào)用C# dll的兩種主要方法的詳細(xì)內(nèi)容,更多關(guān)于Python調(diào)用C# dll的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python?datacompy?找出兩個(gè)DataFrames不同的地方

    Python?datacompy?找出兩個(gè)DataFrames不同的地方

    本文主要介紹了Python?datacompy?找出兩個(gè)DataFrames不同的地方,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-05-05
  • pyinstaller還原python代碼過程圖解

    pyinstaller還原python代碼過程圖解

    這篇文章主要介紹了pyinstaller還原python代碼過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Python 模擬動(dòng)態(tài)產(chǎn)生字母驗(yàn)證碼圖片功能

    Python 模擬動(dòng)態(tài)產(chǎn)生字母驗(yàn)證碼圖片功能

    這篇文章主要介紹了Python 模擬動(dòng)態(tài)產(chǎn)生字母驗(yàn)證碼圖片,這里給大家介紹了pillow模塊的使用,需要的朋友可以參考下
    2019-12-12
  • Python中實(shí)現(xiàn)高效的列表過濾多種方法示例

    Python中實(shí)現(xiàn)高效的列表過濾多種方法示例

    這篇文章主要給大家介紹了關(guān)于Python中實(shí)現(xiàn)高效的列表過濾的多種方法,包括基礎(chǔ)的for循環(huán)、列表推導(dǎo)式、filter函數(shù)、itertools模塊,以及高級(jí)的pandas和numpy庫,我們還討論了生成器的使用,以及在實(shí)際場景中的應(yīng)用,需要的朋友可以參考下
    2024-12-12
  • Python 中l(wèi)ist ,set,dict的大規(guī)模查找效率對比詳解

    Python 中l(wèi)ist ,set,dict的大規(guī)模查找效率對比詳解

    這篇文章主要介紹了Python 中l(wèi)ist ,set,dict的大規(guī)模查找效率對比詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • PyTorch環(huán)境中CUDA版本沖突問題排查與解決方案

    PyTorch環(huán)境中CUDA版本沖突問題排查與解決方案

    在使用 PyTorch 進(jìn)行深度學(xué)習(xí)開發(fā)時(shí),CUDA 版本兼容性問題是個(gè)老生常談的話題,本文將通過一次真實(shí)的排查過程,剖析 PyTorch 虛擬環(huán)境自帶 CUDA 運(yùn)行時(shí)庫與系統(tǒng)全局 CUDA 環(huán)境沖突的場景,需要的朋友可以參考下
    2025-02-02
  • OneFlow源碼解析之Eager模式下Tensor存儲(chǔ)管理

    OneFlow源碼解析之Eager模式下Tensor存儲(chǔ)管理

    這篇文章主要為大家介紹了OneFlow源碼解析之Eager模式下Tensor的存儲(chǔ)管理實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • python子線程退出及線程退出控制的代碼

    python子線程退出及線程退出控制的代碼

    這篇文章主要介紹了python子線程退出及線程退出控制的代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Python繪圖之二維圖與三維圖詳解

    Python繪圖之二維圖與三維圖詳解

    這篇文章主要介紹了Python繪圖之二維圖與三維圖詳解,文中通過示例代碼與效果圖片一一對照介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • python Tkinter版學(xué)生管理系統(tǒng)

    python Tkinter版學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了python Tkinter版學(xué)生管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評論

钟山县| 德格县| 恩施市| 井陉县| 白水县| 揭东县| 峨山| 交口县| 咸宁市| 柏乡县| 仙游县| 博湖县| 乾安县| 常州市| 山阴县| 瓦房店市| 崇信县| 万年县| 三亚市| 广宁县| 霍邱县| 乌苏市| 罗江县| 连平县| 临安市| 乌拉特前旗| 桑植县| 团风县| 新晃| 金阳县| 旺苍县| 松溪县| 浮梁县| 铜川市| 沁阳市| 邯郸县| 浦县| 武清区| 宁海县| 双柏县| 凌源市|