如何获取Cython编译.pyx文件生成的对应有效C++代码实现
Cython编译.pyx为.cpp及定位对应代码片段的问题
问题场景
我有一个简单的helloworld.pyx文件,想了解Cython如何将它编译为.cpp文件,同时定位到对应我代码的具体C++执行片段。编译后生成的.cpp文件有近3000行,大部分是框架代码,找到的片段仅为常量定义,并非有效执行逻辑,希望能得到像Stack Overflow案例中那样干净可编译的代码。
我的helloworld.pyx内容
print("Hello world")
使用的setup.py配置
from setuptools import setup, Extension from Cython.Build import cythonize extensions = [ Extension( "helloworld", sources=["helloworld.pyx"], language="c++" ), ] setup(ext_modules = cythonize(extensions))
编译命令
python3 setup.py build_ext --inplace
解决方案
1. 定位对应代码的C++执行片段
生成的.cpp文件中,print("Hello world")对应的执行逻辑会围绕Python C API调用展开,你可以通过以下方式定位:
- 搜索你找到的常量
__pyx_k_Hello_world,找到它被使用的位置; - 查找模块初始化函数(通常命名为
__pyx_pf_10helloworld___init__或类似)。
对应的核心执行片段大概如下:
__pyx_t_1 = PyUnicode_FromString(__pyx_k_Hello_world); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_GetGlobalName(__pyx_n_s_print); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_t_3 = PyObject_CallObject(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) Py_DECREF(__pyx_t_3); __pyx_t_3 = 0; Py_DECREF(__pyx_t_2); __pyx_t_2 = 0;
这段代码本质是通过Python C API调用print函数,完成字符串输出的逻辑。
2. 生成更干净的C++代码
要得到简洁可编译的生成代码,可通过以下方式优化:
- 指定Python版本,减少兼容代码;
- 添加编译优化选项;
- 直接使用C++原生逻辑替代Python内置函数。
修改后的setup.py:
from setuptools import setup, Extension from Cython.Build import cythonize extensions = [ Extension( "helloworld", sources=["helloworld.pyx"], language="c++", extra_compile_args=["-O3"] # 开启编译优化 ), ] setup( ext_modules = cythonize( extensions, compiler_directives={"language_level": "3"}, # 指定Python3语法 annotate=True # 生成HTML注释文件,对应Cython与C++代码位置 ) )
如果想进一步贴近原生C++,可修改helloworld.pyx直接调用C++标准库:
from libcpp.iostream cimport cout cout << "Hello world" << endl;
这样生成的代码会大幅减少对Python API的依赖,代码量更精简,逻辑更贴近原生C++。
内容的提问来源于stack exchange,提问作者JOKKINATOR
相关产品推荐
相关产品推荐

