【发布时间】:2016-04-13 20:29:39
【问题描述】:
我正在将 Python 模块移植到 Windows。我有一个玩具示例如下。
文件夹结构为:
foo/
libfoo/
foo.c
setup.py
setup.py
from setuptools import setup, Extension
sources = ['libfoo/foo.c']
foo = Extension('libfoo',
sources = sources,
define_macros = None,
include_dirs = ['./libfoo'],
libraries = None,
library_dirs = None,
)
setup(name = 'foo',
ext_modules = [foo],
install_requires = ['setuptools'],
)
libfoo/foo.c(为了完整性)
#include <stdio.h>
void foo() {
printf("Hello World!");
}
当我尝试安装包时,遇到错误。
C:\Users\user\foo>python setup.py install
running install
running bdist_egg
running egg_info
creating foo.egg-info
writing requirements to foo.egg-info\requires.txt
writing foo.egg-info\PKG-INFO
writing top-level names to foo.egg-info\top_level.txt
writing dependency_links to foo.egg-info\dependency_links.txt
writing manifest file 'foo.egg-info\SOURCES.txt'
reading manifest file 'foo.egg-info\SOURCES.txt'
writing manifest file 'foo.egg-info\SOURCES.txt'
installing library code to build\bdist.win32\egg
running install_lib
running build_ext
building 'libfoo' extension
creating build
creating build\temp.win32-2.7
creating build\temp.win32-2.7\Release
creating build\temp.win32-2.7\Release\libfoo
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox
/MD /W3 /GS- /DNDEBUG -I./libfoo -IC:\Python27\include -IC:\Python27\PC /Tclibfo
o/foo.c /Fobuild\temp.win32-2.7\Release\libfoo/foo.obj
foo.c
creating build\lib.win32-2.7
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\link.exe /DLL /nologo
/INCREMENTAL:NO /LIBPATH:C:\Python27\libs /LIBPATH:C:\Python27\PCbuild /EXPORT:i
nitlibfoo build\temp.win32-2.7\Release\libfoo/foo.obj /OUT:build\lib.win32-2.7\l
ibfoo.pyd /IMPLIB:build\temp.win32-2.7\Release\libfoo\libfoo.lib /MANIFESTFILE:b
uild\temp.win32-2.7\Release\libfoo\libfoo.pyd.manifest
LINK : error LNK2001: unresolved external symbol initlibfoo
build\temp.win32-2.7\Release\libfoo\libfoo.lib : fatal error LNK1120: 1 unresolv
ed externals
error: command 'c:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\BIN\\l
ink.exe' failed with exit status 1120
distutils 包(在本例中为 setuputils)似乎总是会从共享扩展中导出一个符号,即“init + extension_name”[Link]。
在 Windows 链接器“EXPORT”选项[Link] 中指定,但找不到符号。
帮助?
编辑:C 代码不使用 Python C API,即“#include”。这是因为该项目的目标是采用现有的 C 库并通过 Python 扩展将其封装在 Python 包装器中。该软件包适用于 Unix/Linux。
【问题讨论】:
-
您是否真的在尝试构建一个“libfoo”扩展模块,该模块需要在导入扩展时定义一个由 Python 调用的
initlibfoo函数?还是您只是使用 setuptools 来编译共享库?如果是后者,您需要为 Windows DLL 做的第一件事是使用__declspec(dllexport)或.DEF file 定义导出的符号。 -
@eryksun 我相信是后者。目的是在安装包时构建“libfoo”扩展。当解释器导入包“foo”即“import foo”时,类对象将加载 DLL(或 .pyd?)。如果这没有意义,请告诉我。
-
一个 .pyd 只是一个 DLL。听起来这就是你想要的,即 foo.pyd 链接到 libfoo.dll 并将函数包装在 libfoo.dll 中。从让 libfoo.dll 自己工作开始,只需从命令行手动构建它(无需 Python 或 setuptools)。然后按照creating an extension module 的文档进行操作。
标签: python windows linker setuptools python-extensions