在Windows上构建64位C Python扩展

25
我提出这个问题是因为我需要构建一个特定的模块(aspell_python,http://wm.ite.pl/proj/aspell-python/),以便与运行在 Windows 7(64位)机器上的 64 位 Python 2.6 配合使用。我也一直想知道如何使用 C 代码加速某些函数,所以我希望将来能制作自己的外部 C 模块供 Python 使用。 请问有人可以告诉我成功构建 64 位 Python C 扩展所需的步骤吗?我熟悉 Python 和 C,但不了解 Visual Studio 或 Windows 特定的开发事项。我试图按照 Python 网站上的官方指南(http://docs.python.org/extending/windows.html#building-on-windows)使用 Visual Studio 2008(这是这里唯一可用的商业产品),但即使是最基本的示例也无法构建。

5
即使是最基本的示例,也要说明其失败的原因。 - Prof. Falken
1
例如:在按照每个方向后,当我尝试构建example_nt时,我得到了链接器错误,它找不到python26.lib。然后我尝试使用与我的Python版本一起分发的python26.lib,但这只导致了两个链接器错误:1>example.obj:错误LNK2019:在函数_ex_foo中引用未解析的外部符号__imp___Py_NoneStruct 1>example.obj:错误LNK2019:在函数_initexample中引用未解析的外部符号__imp__Py_InitModule4 - Alexandros
之后,我尝试通过使用VS2008从源代码构建整个Python 2.6项目来构建python26.lib,当然会产生许多错误。但是它生成了一个python26_d.lib,但与example_nt一起编译仍然会出现链接器错误。 - Alexandros
如果您已经安装了带有64位编译器的Visual Studio 2008专业版,那么使用“python setup.py build”构建example_nt应该可以在Python 2.6.6 AMD64上开箱即用。 - cgohlke
当运行“python setup.py build”时,它给了我一个错误:raise ValueError(str(list(result.keys()))) ValueError: [u'path']。 - Alexandros
3
很可能您没有正确安装Visual Studio 2008 Professional。64位编译器是需要在安装时启用的选项。如果您使用的是Visual Studio 2008 Express,则不包含64位编译器。 - cgohlke
2个回答

9

我曾经通过在扩展源代码的顶级目录下从“Visual Studio 2008 x64 Win64命令提示符”运行以下命令,成功地为Python编译了C扩展:

set DISTUTILS_USE_SDK=1
set MSSdk=1
python setup.py install

这似乎在我的 VS 2012 上可以工作... 我遇到了很多困难。 - Mark Harviston

2
我会使用Shed Skin:只需下载、解压缩,运行init bat,然后编译您的Python代码。 如果这不起作用,并且您可以让Microsoft的C编译器环境正常工作,请尝试Cython此教程比较了普通的Python扩展和其生成的C版本。更新摘录:

c_prime.pyx:

def calculate(long limit):
    cdef long current
    cdef long divisor
    primes = []
    divisor = 0
    for current in range(limit):
        previous = []
        for divisor in range(2, current):
            if current % divisor == 0:
                break
        if divisor == current - 1:
            primes.append(current)
    return primes

setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
  name = 'PrimeTest',
  ext_modules=[
    Extension('c_prime', ['c_prime.pyx'])
    ],
  cmdclass = {'build_ext': build_ext}
)
编译:

python setup.py build_ext --inplace --compiler=msvc

test_prime.py:

from timeit import Timer

t = Timer('c_prime.calculate(10000)', 'import c_prime')
reps = 5
print(sum(t.repeat(repeat=reps, number=1)) / reps)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,