【问题标题】:cython prints wrong values of numbers bigger than 65535cython 打印大于 65535 的错误值
【发布时间】:2017-10-12 06:33:45
【问题描述】:

我发现将数字传递给 cython 中的函数的奇怪行为,其值大于 65535。但这只有在将这些数字传递给函数时才会出现。如果我将它们定义为

cdef long long a = 145574697

一切正常。为了澄清我的问题,我传递了我用来调查这个问题的两个虚拟函数

def bigNum1():
    cdef long long a = 500000
    cdef long long b = 10547746498
    cdef long long c = 65536
    cdef long long d = 65535
    print(a, b, c, d)


def bigNum2(long long a, long long b, long long c, long long d):
    print(a, b, c, d)

以及为获取“.pyd”文件而调用的“setup.py”。

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


setup(
    ext_modules = cythonize("bigNumbers.pyx")
)

之后我用命令创建了“.pyd”文件

python setup.py build_ext --inplace

使用命令提示符。使用的 c 编译器是 gcc。

如果我随后调用“bigNum1”或“bigNum2”,将产生以下输出。

bigNum1: (500000, 10547746498, 65536, 65535)
bigNum2: (41248, 442029762, 0, 65535).

如您所见,所有大于 65535 的数字都显示错误,使用 bigNum2。跟着你看这个函数的调用。

import bigNumbers

bigNumbers.bigNum1()

a = 500000
b = 10547746498
c = 65536
d = 65535


bigNumbers.bigNum2(a, b, c, d)

希望您能理解我的问题。 我的猜测是,我在 bigNum2 中做了一个错误的声明,导致类型错误,或者我必须在将数字传递给此方法之前进行某种类型转换。

编辑:

这是cmd提示过程中显示的文字

python setup.py build_ext --inplace
Compiling bigNumbers.pyx because it changed.
[1/1] Cythonizing bigNumbers.pyx
running build_ext
building 'bigNumbers' extension
D:\WinPython3610\cgg64Bit\bin\gcc.exe -mdll -O -Wall -ID:\WinPython3610\python-3
.6.1.amd64\include -ID:\WinPython3610\python-3.6.1.amd64\include -c bigNumbers.c
 -o build\temp.win-amd64-3.6\Release\bignumbers.o
writing build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def
D:\WinPython3610\cgg64Bit\bin\gcc.exe -shared -s build\temp.win-amd64-3.6\Releas
e\bignumbers.o build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def -L
D:\WinPython3610\python-3.6.1.amd64\libs -LD:\WinPython3610\python-3.6.1.amd64\P
Cbuild\amd64 -lpython36 -lvcruntime140 -o L:\User\neon3_worksp
ace\CythonSource\src\bigNumbers.cp36-win_amd64.pyd

EDIT2:

我使用 cython 0.25.2 附带的 Winpython 包“WinPython 3.6.1.0Qt5-64bit”。但是我用 pip 升级它以获得最新版本。

首先,我尝试使用此处的教程获取我的 .pyd。

http://docs.cython.org/en/latest/src/quickstart/build.html

但在构建过程中,我收到一条错误消息“错误:无法找到 vcvarsall.bat”。这就是为什么我决定将 Mingw 与 gcc 一起使用。但这也产生了一个错误,在这篇文章中有描述。

ValueError: Unknown MS Compiler version 1900

我用 Indrajit Kanjilal 的回答解决了这个问题。我们现在就在那里。我可以创建一个 .pyd 文件,可以调用该函数,但如果该值大于 65535,则会发生错误。希望有帮助。

【问题讨论】:

  • 无法用 python2.7/cython0.25/MSVS 重现
  • 预期,但我无法在 Linux Python3.5/Cython 0.23.4/gcc 6 上重现。
  • cdef bigNum2将bigNum2定义为C函数怎么样?
  • Marcel S.,您获得的结果强烈表明,在某些时候,Python 安装、Cython 安装和开发环境之间存在混淆。能否给出所有这些组件的安装方法?
  • 在构建本机代码时混合编译器永远不会有好的结果。您已经 (a) Visual Studio 使用 (b) Mingw gcc 构建的 cython 和自定义源构建了 Python 3.6,所有这些都链接到 VS 构建的 python 3.6 .. 是的,祝你好运。使用 VS 2015 安装和重建以与 Python 3.6 一起使用,或者通过 conda 安装一个全新的环境,所有内容都由同一个编译器编译。

标签: python cython python-3.6 cythonize


【解决方案1】:

简而言之,链接时不要混合编译器。

这里的问题与 Cython 无关,但与使用有关

  1. Visual Studio 构建的 Python 分发版
  2. MingW GCC 构建的 Python 扩展

并将它们连接在一起。由于编译器实现的差异,特别是上述 Visual Studio 实现 long ints 的方式不同,这会以各种有趣的方式中断。

在编写 Python 扩展时,最好始终使用与 Python 发行版相同的编译器来构建扩展。

对于官方 Python 发行版,这些是用于 Py 2.6 到 3.6 的 Visual Studio 9 到 15 - 请参阅 Which Microsoft Visual C++ compiler to use with a specific Python version on the Python wiki

解决方案是使用 Visual Studio 15.0(又名 VS 2014,用于 Python 3.6),或者使用 conda 环境,该环境使用 GCC 构建包括 Python 在内的所有内容。

【讨论】:

    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2020-02-10
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多