首页 > 编程语言 >如何将Python项目封装为C#可直接调用的DLL

如何将Python项目封装为C#可直接调用的DLL

来源:互联网 2026-07-01 08:13:06

Python 项目无法直接编译为 Windows 原生 .dll 供 C# P/Invoke 调用,但可通过 Python.NET 实现无缝集成:在 C# 进程内嵌入 Python 运行时,直接调用 Python 类、函数及第三方库(如 OpenCV、Pandas),无需进程间通信或 EXE 封装。

Python 项目无法直接编译为 Windows 原生 .dll 供 C# P/Invoke 调用,但可通过 Python.NET 实现无缝集成:在 C# 进程内嵌入 Python 运行时,直接调用 Python 类、函数及第三方库(如 OpenCV、Pandas),无需进程间通信或 EXE 封装。

首先需要明确一点:Python 项目无法像 C++ 那样直接编译成 Windows 原生的 .dll 文件,供 C# 通过 P/Invoke 机制调用。但这并不意味着没有可行的解决方案。借助 Python.NET 这一成熟的桥梁,完全可以在 C# 进程内部嵌入 Python 运行时,直接调用 Python 的类、函数,甚至包括 OpenCV、Pandas 等第三方库,整个过程在同一个进程内完成,既不需要创建新进程,也无需将 Python 打包为 exe。

换句话说,“将 Python 项目转换为 C# 可直接引用的 .dll”并不是字面意义上的编译——Python 作为解释型语言,不具备原生的 .NET IL 输出能力。但通过 Python.NET,实际效果几乎一致:C# 程序可以加载并执行 Python 代码,访问 Python 对象——包括自定义类、NumPy 数组、OpenCV 的 cv2 模块、Pandas DataFrame 等。这彻底绕开了 Process.Start() 的启动开销、标准流解析的误差以及跨进程数据序列化带来的各种问题。

长期稳定更新的攒劲资源: >>>点此立即查看<<<

正确实践:使用 Python.NET 替代 EXE 调用

  1. 安装 Python.NET NuGet 包
    在 C# 项目中执行命令:

    dotnet add package Python.Runtime

    或在 Visual Studio 的 NuGet 包管理器中搜索并安装 Python.Runtime

  2. 准备 Python 模块(无需打包)
    保留原始的 .py 文件即可,例如 math_operation.py。关键是要让 Python 运行时能够找到该文件,建议将其放置在项目的 Resources 目录下,或通过代码指定路径:

    # math_operation.py
    class A:
        def add(self, a, b):
            return int(a + b)  # 显式转为 int,避免类型不匹配
        def subtract(self, a, b):
            return int(a - b)
  3. 在 C# 中直接调用 Python 类
    初始化 Python 运行时后,导入模块、实例化类、调用方法一气呵成:

    using Python.Runtime;
    
    class Program
    {
        static void Main(string[] args)
        {
            // 初始化 Python 运行时(自动发现或指定路径)
            // 注意:Python 版本需与 Python.NET 兼容,推荐 3.8–3.11
            PythonEngine.Initialize();
    
            // 设置 Python 模块搜索路径(可选)
            using (Py.GIL()) // 获取全局解释器锁
            {
                // 导入 Python 模块
                dynamic mathModule = Py.Import("math_operation");
                // 实例化 Python 类
                dynamic pyObj = mathModule.A();
                // 直接调用方法(参数自动转换,返回值自动映射)
                int result1 = pyObj.add(3, 4);
                int result2 = pyObj.subtract(10, 6);
                Console.WriteLine($"The sum of 3 and 4 is: {result1}");
                Console.WriteLine($"The difference between 10 and 6 is: {result2}");
            }
    
            PythonEngine.Shutdown(); // 清理资源(进程退出时自动释放,可省略)
        }
    }

关键注意事项

  • Python 环境依赖:Python.NET 要求系统已安装对应版本的 Python(例如 python39.dll),并且 C# 应用的架构必须与 Python 一致(x64 或 x86)。建议部署时将 Python 运行时(如嵌入式 Python)与应用一同分发。
  • 第三方库支持:OpenCV、Pandas 等包含 C 扩展的库均可正常工作,前提是其 DLL 路径已加入 PATH,或通过 PythonEngine.SetPythonHome() 显式指定 Python 环境根目录。
  • 线程安全:每次调用 Python API 前必须使用 using (Py.GIL()) 获取全局解释器锁;多线程场景下需特别注意 GIL 的管理。
  • 异常处理:Python 抛出的异常会以 PythonException 形式传递到 C# 端,应使用 try-catch 捕获,并检查 PyErr_Occurred()
  • 性能考量:与纯 C# 相比,首次调用时有初始化开销,但后续调用速度接近原生——因为没有进程创建、IPC、JSON/XML 序列化等瓶颈。

总结

放弃那些先将 Python 打包为 exe 再使用 Process.Start() 调用的低效方案。Python.NET 是将 Python 逻辑深度集成到 C# 应用中的工业级标准做法。它不仅解决了 null 返回、类型转换失败、环境隔离等问题,更让 C# 能直接操作 Python 对象——无论是调用 cv2.imread() 加载图像,还是将 pandas.DataFrame 转换为 DataTable,都在统一的内存空间内完成。只要正确配置环境、合理管理 GIL,并注意异常与资源释放,即可构建高性能、易维护的混合应用。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。