当前位置: 首页 > article >正文

将python代码文件转成Cython 编译问题集

准备setup.py

from distutils.core import setup
from Cython.Build import cythonize
import glob

# 指定目标目录 python setup.py build -c mingw32
target_dir = "src"

# 使用glob模块匹配目录中的所有.pyx文件
pyx_files = glob.glob(target_dir + "/**/*.py", recursive=True)
print(f"pyx_files={pyx_files}")
# 将匹配到的所有.pyx文件进行编译
setup(ext_modules=cythonize(pyx_files, language_level=3))

运行命令:

python setup.py build -c mingw32

不出意外就会将src目录的文件全部编译城.c文件。出意外就看下面的错误集↓↓↓

-----------

众所周知,很多Python的库都需要编译(可能是用了Cython),这时直接用pip安装会报错:error: Microsoft Visual C++ 14.0 is required.

不知为何,我的电脑死活不能安装上VC,只能用mingw作为编译器。

附:MinGW-w64 密码:2jfy,tdm64-gcc tdm-gcc(32位)

最新版:tdm-gcc GCC with the MCF thread model MinGW-w64

环境变量:[Windows配置MinGW环境变量]

然后编辑你的 Python 路径/Lib/distutils/distutils.cfg 或者 %USERPROFILE%\pydistutils.cfg

[build]
compiler=mingw32
[build_ext]
compiler = mingw32

# To solve the gcc error of "error: enumerator value for '__pyx_check_sizeof_voidp' is not an integer constant"
# if you have a mingw for 64bit then
# refer to https://docs.python.org/zh-cn/3/distutils/configfile.html
# you can also refer to https://github.com/cython/cython/issues/3405#issuecomment-596975159
define = MS_WIN64 

仍然会报错 Unknown MS Compiler version XXXX

编辑你的Python路径/Lib/distutils/cygwinccompiler.py

elif msc_ver == '1600':
    # VS2010 / MSVC 10.0
    return ['msvcr100']

后添加

elif msc_ver == '1927':
    # MinGW64 with gcc 8.3.0
    return ['msvcr120'] # seem to be a dynamic-linker program name for command `ld`

其中1927改为你的Compiler version

----------------------

然后编译又报错:

error: enumerator value for '__pyx_check_sizeof_voidp' is not an integer constant

解决办法:

您可以简单地将此补丁应用于%PYTHON_DIR%\include\pyconfig.h

--- pyconfig.h	2016-01-27 10:54:56.000000000 +0300
+++ pyconfig.h	2016-03-28 11:46:48.000000000 +0300
@@ -100,6 +100,12 @@
 
 /* Compiler specific defines */
 
+#ifdef __MINGW32__
+#ifdef _WIN64
+#define MS_WIN64
+#endif
+#endif
+
 /* ------------------------------------------------------------------------*/
 /* Microsoft C defines _MSC_VER */
 #ifdef _MSC_VER
# --inplace 将放在原地
# 指定目标目录 python setup.py build_ext  -c mingw32

setup.py完整如下:

import os
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import glob

# 获取当前脚本所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))

# 指定源代码目录
source_dir = os.path.join(current_dir, "src")

# 使用glob模块匹配目录中的所有.pyx文件
pyx_files = glob.glob(os.path.join(source_dir, "**/*.py"), recursive=True)

# 保持相对路径
relative_pyx_files = [os.path.relpath(pyx, current_dir) for pyx in pyx_files]
print(f"pyx_files={relative_pyx_files}")

# 指定目标目录
target_dir = os.path.join(current_dir, "build")

# 将匹配到的所有.pyx文件进行编译
extensions = [Extension(os.path.splitext(pyx)[0].replace(os.sep, '.'), [pyx]) for pyx in relative_pyx_files]

setup(
    ext_modules=cythonize(extensions, language_level=3),
    script_args=['build_ext', '--build-temp', target_dir, '-c', 'mingw32'],
)

通过执行python setup.py 就会将当前py文件转成pyd

-----------------

在Python开发中,我们经常需要保护我们的代码不被轻易查看或修改。同时,我们也希望提高代码的执行效率。将Python文件编译为.pyd动态链接库是一种可以实现这两点的有效方法。.pyd文件类似于Windows平台上的.dll文件,是一种动态链接库,包含了编译后的二进制代码。通过这种方式,我们可以隐藏源代码,同时利用编译的优势提高代码的执行效率。
要实现这一目标,我们需要使用Cython工具。Cython是一个Python到C的编译器,可以将Python代码转换为C代码,然后编译成.pyd文件。
下面是一个简单的步骤指南:

  1. 安装Cython:首先,你需要在你的开发环境中安装Cython。可以通过pip安装,命令如下:
     
      
    1. pip install cython
  2. 创建Cython文件:创建一个新的Python文件,后缀名为.pyx。这个文件将包含你要编译的Python代码。例如,你可以创建一个名为example.pyx的文件,其中包含以下内容:
     
      
    1. def say_hello(name):
    2. print(f'Hello, {name}!')
  3. 编写setup.py:接下来,你需要创建一个setup.py文件,用于配置编译过程。以下是一个简单的setup.py示例:
     
      
    1. from setuptools import setup
    2. from Cython.Build import cythonize
    3. setup(
    4. ext_modules = cythonize('example.pyx')
    5. )
  4. 编译为C文件:在命令行中进入包含setup.py和example.pyx的目录,然后运行以下命令:
     
      
    1. pip install -e . # 或者 python setup.py build_ext --inplace
    这将会生成一个名为example.c的C源文件和一个名为example.so(Linux/macOS)或example.pyd(Windows)的共享库文件。请注意,生成的共享库文件名可能因平台而异。在Windows上,你需要将example.so改为example.pyd。
  5. 使用编译后的模块:现在你可以像普通Python模块一样导入并使用你的.pyd文件了。例如:
     
      
    1. import example
    2. example.say_hello('World') # 输出:Hello, World!
    通过以上步骤,你就可以将Python代码编译为.pyd动态链接库,实现代码的加密和加速。编译后的代码不仅更加安全,而且执行效率更高。这对于需要保护核心算法或希望提高程序性能的项目来说非常有用。当然,Cython还提供了更多高级功能,如类型检查和C API集成,可以根据需要进行探索和使用。

参考:将Python文件编译为.pyd动态链接库:加密与加速的完美结合


http://www.kler.cn/news/318485.html

相关文章:

  • python中实用工具与自动化脚本
  • typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍
  • 滚雪球学SpringCloud[6.3讲]: 分布式日志管理与分析
  • 常见统计量与其抽样分布
  • python异步处理
  • [SDX35+WCN6856]SDX35 + WCN6856 WiFi 起来之后,使用终端连接会导致系统重启
  • dotnet4.0编译问题
  • 【系统架构设计师】专题:系统质量属性和架构评估
  • 康养为松,智能为鹤:华为全屋智能画出的松鹤长春图
  • 2024.9.24 数据分析
  • 努比亚z17努比亚NX563j原厂固件卡刷包下载_刷机ROM固件包下载-原厂ROM固件-安卓刷机固件网
  • 智慧城市主要运营模式分析
  • [附源码]宠物领养管理系统+SpringBoot
  • css实现居中的方法
  • C++ prime plus-4-编程练习
  • vue echarts tooltip使用动态模板
  • Web3技术在元宇宙中的应用:从区块链到智能合约
  • 搜维尔科技:手指舞测试Manus VR数据手套手指追踪功能
  • HtmlCss 基础总结(基础好了才是最能打的)五
  • 代码随想录算法训练营第二十八天| 122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II、1005.K次取反后最大化的数组和
  • 线程知识点补充
  • uniapp map设置高度为100%后,会拉伸父容器的高度
  • 练习题 - Django 4.x Models Meta 元数据选项
  • C++类和对象(中)【下篇】
  • 考研数据结构——C语言实现插入排序
  • 2024百度的组织架构和产品分布
  • Java Collectors工具类
  • js进阶——词法作用域
  • 无人机蜂群作战会成为未来战争的主要形式吗,该如何反制呢?
  • 前端——阿里图标的使用