cython 打印大于 65535 的数字的错误值

cython prints wrong values of numbers bigger than 65535

我发现在 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

编辑2:

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

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

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

但是在构建过程中我收到一条错误消息 "error: Unable to find vcvarsall.bat"。这就是为什么我决定将 Mingw 与 gcc 一起使用。但这也产生了一个错误,在 post.

上有描述

ValueError: Unknown MS Compiler version 1900

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

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

这里的问题与 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 环境构建所有内容,包括 Python使用 GCC。