Cython + Windows 8.1 + VS Express 2013

0 投票
2 回答
748 浏览
提问于 2025-04-18 14:49

这是另一个关于Windows和Cython的问题……Cython确实能成功编译一些简单的脚本(虽然不是全部),但大多数情况下gcc会报错。我已经在Setup.py中配置了使用MingW32作为编译器,并在Setup.cfg中进行了设置。我还安装了MCVS Express,但似乎要使用它作为编译器需要2008版本,而这个版本现在找不到了。我读了很多关于在Windows上无法使用Cython的资料,但还是找不到解决办法。看起来任何包含cdef的脚本都会编译失败。有人能帮帮我吗?

配置:

  • Windows 8.1(当然是64位)
  • Python 2.7.6 32位
  • Cython 0.20.2,已为32位Windows预编译
  • Microsoft Visual Studio Express 2013

测试项目:

  • test.py
  • setup.py
  • setup.cfg

Setup.cfg:

[build]
compiler = mingw32

Setup.py:

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


setup(
    ext_modules = cythonize("test.py")
)

有效的test.py:

def say_hello_to(name):
    print("Hello %s!" % name)

失败的test2.py(相应修改Setup.py):

def primes(int kmax):
cdef int n, k, i
cdef int p[1000]
result = []
if kmax > 1000:
    kmax = 1000
k = 0
n = 2
while k < kmax:
    i = 0
    while i < k and n % p[i] != 0:
        i = i + 1
    if i == k:
        p[k] = n
        k = k + 1
        result.append(n)
    n = n + 1
return result

Mingw32错误输出:

PS C:\Users\Raoul\Desktop\cython_trys> python setup.py build_ext --inplace
Compiling test2.py because it changed.
Cythonizing test2.py

Error compiling Cython file:
------------------------------------------------------------
...
def primes(int kmax):
              ^
------------------------------------------------------------

test2.py:1:15: Expected ')', found 'kmax'
Traceback (most recent call last):
  File "setup.py", line 6, in <module>
    ext_modules = cythonize("test2.py")
  File "C:\Python27\lib\site-packages\Cython\Build\Dependencies.py", line 798, in cythonize
cythonize_one(*args[1:])
  File "C:\Python27\lib\site-packages\Cython\Build\Dependencies.py", line 915, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: test2.py

2 个回答

1

我不太确定这是不是问题的根源,但很可能是:

错误信息是:

cannot open output file C:\Users\Raoul\Desktop\cython_trys\test.pyd: Permission denied

这可能不是因为你没有权限在 cython_trys 里创建新文件,而是因为已经有一个名为 test.pyd 的文件被独占打开了,所以它被锁住了,因此尝试用新文件覆盖它(就像 gcc 正在尝试的那样)会失败。

为什么这个文件会被打开和锁住呢?

如果你在一个交互式的 Python 会话中,或者在一个脚本里执行了 import test 来测试第一个成功的 test.py,而且你让它一直运行着,那么它就会一直保持 test.pyd 文件打开。最简单的解决办法就是退出那个 Python 会话或者脚本。

或者,你也可以选择创建一个不同名字的新文件,而不是重复使用同一个文件。


Unix 系统的人写的教程通常不会提到这个问题,因为在 Unix 中,文件不会被删除,直到你在文件系统中移除最后一个链接 并且 关闭任何进程中对它的最后一个文件句柄。所以,你可以用 rm 删除一个文件,或者在上面写一个新文件,而任何仍然打开这个文件的人依然可以正常读取和写入它。但在 Windows 中,一旦最后一个文件系统链接消失,这个文件就可以被删除,即使还有其他人持有它的句柄。这显然是个大问题。因此,Windows 到处使用独占访问锁来防止你做这样的事情。

1

新问题就是你把文件命名成了 test2.py,而不是 test2.pyx

如果你手动操作,Cython 不在乎你把文件叫什么——只要你告诉它要把某段代码当作 Cython 代码来编译,它就会编译。

但是,当你使用 cythonize 函数来创建你的 ext_modules 时,它会根据文件的后缀来猜测文件类型:.py 表示纯 Python 代码,.pyx 表示 Cython 代码。所以,它试图把你的代码当作纯 Python 来编译,当然了,int kmax 在 Python 中不是一个有效的参数。(你在其他测试中遇到的 cdef 错误也是这个原因。)

撰写回答